diff --git a/gatsby-browser.js b/gatsby-browser.js index e6d4c93ee..aa4d482bb 100644 --- a/gatsby-browser.js +++ b/gatsby-browser.js @@ -1,3 +1,15 @@ +const originalFetch = window.fetch.bind(window); +window.fetch = (input, init) => { + const url = typeof input === 'string' ? input : input?.url ?? ''; + if (url.includes('radiant-styles/public/img/rd-icons/rd-icons-sprite/rd-icons.svg')) { + return Promise.resolve(new Response('', { + status: 200, + headers: { 'Content-Type': 'image/svg+xml' }, + })); + } + return originalFetch(input, init); +}; + exports.onClientEntry = () => { // Dynamic imports so @thoughtspot/radiant-react (which reads `window` at // module-load time) is never evaluated during Gatsby's SSR build. diff --git a/modules/ROOT/pages/.write-test b/modules/ROOT/pages/.write-test new file mode 100644 index 000000000..0e808f9c2 --- /dev/null +++ b/modules/ROOT/pages/.write-test @@ -0,0 +1 @@ +write access test - delete me \ No newline at end of file diff --git a/modules/ROOT/pages/about-rest-apis.adoc b/modules/ROOT/pages/about-rest-apis.adoc index 3ac6e7ca6..02d98842a 100644 --- a/modules/ROOT/pages/about-rest-apis.adoc +++ b/modules/ROOT/pages/about-rest-apis.adoc @@ -3,28 +3,56 @@ :page-title: ThoughtSpot REST APIs :page-pageid: rest-apis -:page-description: ThoughtSpot REST API provides service endpoints for administration, embedding, and data management. +:page-description: ThoughtSpot REST APIs let you programmatically manage users, groups, and metadata objects, query data, and automate deployments. The REST API v2.0 framework is the current standard for all integrations. -The ThoughtSpot REST API framework lets you create, access, edit, and manage objects and resources in the ThoughtSpot system programmatically. +The ThoughtSpot REST API framework lets you create, access, and manage ThoughtSpot resources programmatically. -ThoughtSpot REST API supports several resource collections and operations in two distinct versions: +== Overview +You can use REST APIs to integrate ThoughtSpot capabilities into your applications and automate workflows, without going through the ThoughtSpot UI. ThoughtSpot REST API endpoints allow you to: -* REST API v1 -+ -The legacy framework with several endpoints to create, edit, administer and manage ThoughtSpot objects and data. +* *Manage users, groups, and roles*. Create and manage user accounts, define groups and privileges, and automate provisioning workflows. +* *Authenticate and manage sessions*. Get authentication tokens for users, including tokens for embedded application users with trusted authentication. +* *Manage metadata objects*. Search, create, update, and delete objects such as Liveboards, Answers, Models, Worksheets, and Tables. Import and export objects as ThoughtSpot Modeling Language (TML) representations. +* *Query data*. Run search queries against your data and fetch Liveboard, Answer, and visualization data in your application. +* *Export reports*. Download Liveboards and Answers in PDF, PNG, CSV, or XLSX formats. +* *Automate deployments*. Move content between environments and Orgs with TML and version control APIs, and manage multi-tenant deployments. +* *Administer your instance*. Configure Orgs, manage connections, set up custom actions, audit activity with system logs, and manage instance settings. +* *Work with AI and Spotter*. Create Spotter conversations, send messages, manage Spotter memory, and share conversations programmatically. + +== When to use REST APIs + +Use REST APIs when you need to: + +* Automate administration tasks such as user provisioning, group management, or scheduled content deployment. +* Fetch data from ThoughtSpot into your own application or service, without embedding ThoughtSpot UI components. +* Build deployment pipelines that promote content across development, staging, and production environments. +* Integrate ThoughtSpot operations into external systems, such as CI/CD tooling, orchestration services, or custom portals. -* REST API v2.0 +If you want to embed interactive ThoughtSpot components such as Liveboards, Search, or Spotter in your application, use the xref:getting-started.adoc[Visual Embed SDK]. The Visual Embed SDK and REST APIs are complementary; embedded applications commonly use REST APIs alongside the SDK for tasks such as token issuance for trusted authentication and metadata automation. + +== REST API versions +ThoughtSpot REST APIs are available in the following versions: + +* REST API v2.0 (Recommended) + +The REST API v2 framework includes a wider set of xref:rest-api-v2-reference.adoc[API endpoints] with enhanced functionality and provides an interactive Playground for ease of use. + +* REST API v1 (Deprecated) + +The xref:rest-api-reference.adoc[legacy REST v1 endpoints] to create, edit, administer and manage ThoughtSpot objects and data. + -The REST API v2.0 framework provides enhanced functionality and improved API experience with an interactive Playground. +include::{path}/rest-apiv1-deprecation-note.adoc[] For more information about the differences between these two REST API versions, see xref:rest-api-v1v2-comparison.adoc[REST API v1 and v2.0 comparison]. == REST API Playground +ThoughtSpot provides an interactive playground to explore and try out API workflows on your own instance or ThoughtSpot trial instance. + +To view the Playground, go to *Develop* > *REST API* > *REST Playground v2.0* in your ThoughtSpot instance, or use the link:https://try-everywhere.thoughtspot.cloud/v2/#/everywhere/api/rest/playgroundV2_0[ThoughtSpot public instance, window=_blank]. -ThoughtSpot users with Developer or Administrator privileges can access the REST API v1 and v2.0 endpoints in the *Develop* tab. The portal provides a separate Playground for each REST API version and lets you explore the API endpoints, request and response workflows. +In the Playground, you can: -* 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**. +* Browse endpoints by resource category and view request and response schemas. +* Try API requests against your instance and inspect live responses. +* View and copy generated code samples for your requests. == 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. @@ -37,11 +65,13 @@ These rate limits are enforced by default on all ThoughtSpot instances. Currentl 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. +== REST API SDKs -== 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: +To integrate v2.0 APIs into your applications faster, ThoughtSpot provides SDK libraries in several languages, including TypeScript and Python. The SDKs wrap endpoint calls, authentication, and typed request and response models. For more information, see xref:rest-api-sdk-libraries.adoc[REST API SDK libraries]. -* xref:rest-api-reference.adoc[REST API v1 Reference] -* xref:rest-api-v2-reference.adoc[REST API v2.0 Reference] +== Related information +* xref:rest-api-v2-getstarted.adoc[Get started with REST API v2.0] +* xref:rest-api-v2-reference.adoc[REST API v2.0 reference] +* xref:rest-apiv2-changelog.adoc[REST API v2.0 changelog] +* xref:rest-api-sdk-libraries.adoc[REST API SDK libraries] diff --git a/modules/ROOT/pages/admin-api.adoc b/modules/ROOT/pages/admin-api.adoc index 315b9711f..7824f5d4c 100644 --- a/modules/ROOT/pages/admin-api.adoc +++ b/modules/ROOT/pages/admin-api.adoc @@ -1,14 +1,16 @@ -= Admin APIs += REST API v1 - Admin API endpoints :toc: true :toclevels: 1 :page-title: Admin APIs -:page-pageid: admin-api +:page-pageid: admin-api-v1 :page-description: The admin API endpoints allow you to view, edit, and manage your cluster configuration -The admin API service allows you to query and update configuration information for a ThoughtSpot cluster. You can also use these APIs to migrate data from one cluster to another. +include::{path}/rest-apiv1-deprecation-note.adoc[] + == Supported operations +The admin API service allows you to query and update configuration information for a ThoughtSpot cluster. You can also use these APIs to migrate data from one cluster to another. include::{path}/admin-api-list.adoc[] diff --git a/modules/ROOT/pages/api-auth-session.adoc b/modules/ROOT/pages/api-auth-session.adoc index 33ddd2ce8..3fc94050b 100644 --- a/modules/ROOT/pages/api-auth-session.adoc +++ b/modules/ROOT/pages/api-auth-session.adoc @@ -6,6 +6,8 @@ :page-pageid: api-auth-session :page-description: To access ThoughtSpot objects and resource endpoints, authenticate and log in to the ThoughtSpot system +include::{path}/rest-apiv1-deprecation-note.adoc[] + To create, access, and modify ThoughtSpot objects and resources through the REST API, you must log in as an authorized user. A successful login operation returns session cookies from the ThoughtSpot system, which must be included in subsequent REST API calls. When using the REST API through a web browser, ThoughtSpot recommends that you use the xref:configure-saml.adoc[SAML SSO] or xref:trusted-authentication.adoc[trusted authentication] service to authenticate to ThoughtSpot. A successful login using the Visual Embed SDK via either of those two methods will establish the session within the web browser. diff --git a/modules/ROOT/pages/api-changelog.adoc b/modules/ROOT/pages/api-changelog.adoc index cb2867e9c..50d909190 100644 --- a/modules/ROOT/pages/api-changelog.adoc +++ b/modules/ROOT/pages/api-changelog.adoc @@ -8,20 +8,164 @@ This page documents the changes introduced in each release of the Visual Embed SDK. For information about the REST API v2.0 changes, see the xref:rest-apiv2-changelog.adoc[REST API v2.0 changelog]. +== Version 1.52.x, September 2026 + +[width="100%" cols="1,4"] +|==== +|[tag greenBackground]#NEW# +a| +[discrete] +===== Spotter conversation sharing in embedded views +Embedding application users can now share a saved Spotter conversation with other users and groups directly from the embedded interface. Recipients can view the shared conversation in a read-only view. +Conversation sharing is turned off by default in embedded views. To enable it, set `enableShareConversation` to `true` in the `spotterShareConversationConfig` object. + +Interface customization settings:: +The SDK also provides the following controls for conversation sharing: + +* `SpotterShareConversationConfig` + +Includes object properties for enabling conversation sharing, label and text overrides for the share button, share modal, recipient picker, and the read-only shared view. For more information, see xref:customize-spotter-sharing.adoc[Customize conversation sharing experience]. +* `sharedConversationId` + +Allows passing conversation ID to the SpotterEmbed when the sharing link is generated for the recipient users in the embedded app. For more information, see xref:customize-spotter-sharing.adoc#_customizing_conversation_sharing_link[Conversation sharing link] + +New action IDs:: +* `Action.SpotterShareConversationButtonHeader` for **Share** button in the Spotter conversation header. +* `Action.SpotterShareConversationMenuItemSidebar` for **Share** menu action in the chat history panel in the sidebar. +* `Action.SpotterShareIncludeNewMessagesCheckbox` for the `include new messages since last shared version` checkbox in the share modal. +* `SpotterSharedConversationBannerDismissButton` for the dismiss button of the data access banner displayed in the shared conversation view. +* `Action.SpotterShareUpToCurrentInfo` for the share modal footer note. +* `Action.SpotterSharedConversationBanner` for the data access banner shown when a recipient opens a shared conversation. +* `Action.SpotterShareStaleInfoBannerDismissButton` for the banner that shows the message, "This data may have changed since the last time you had a chat." +* `Action.SpotterSharedConversationExitButton` for *Exit* button in the read-only view of the shared conversation. + +New host events:: +* `HostEvent.ShareSpotterConversation` + +Opens the Spotter share conversation modal for the given conversation ID. +* `HostEvent.ExitSpotterSharedConversation` + +Exits the read-only view of the shared conversation. +* `HostEvent.CloseSpotterShareConversation` + +Closes the Spotter share conversation modal. + +New embed events:: +* `EmbedEvent.SpotterConversationShared` + +Emitted when a Spotter conversation is shared with the intended recipients. +* `EmbedEvent.SpotterConversationShareRevoked` + +Emitted when access to a shared Spotter conversation is revoked. +* `EmbedEvent.SpotterSharedConversationViewed` + +Emitted when a recipient opens a shared Spotter conversation. +* `EmbedEvent.SpotterShareConversationButtonHeaderClicked` + +Emitted when the Share button in the conversation header is clicked. +* `EmbedEvent.SpotterShareConversationMenuItemSidebarClicked` + +Emitted when the Share action in the menu displayed for a chat in the chat history sidebar. +* `SpotterShareIncludeNewMessagesCheckboxToggled` + +Emitted when the user toggles the "include new messages since last shared version" checkbox in the share modal. +* `EmbedEvent.SpotterShareModalCancelButtonClicked` + +Emitted when the Cancel button in the share conversation modal is clicked. +* `EmbedEvent.SpotterShareStaleInfoBannerDismissed`+ +Emitted when the user dismisses the banner that shows the text, "This data may have changed since the last time you had a chat." +* `EmbedEvent.SpotterSharedConversationExitButtonClicked` + +Emitted when a user exits the shared conversation read-only view. + +|[tag greenBackground]#NEW# a| + +[discrete] +===== Browser history management in embedded application +To override the browser history behavior for embedding application users, you can now set `overrideHistoryState` in the Visual Embed SDK. Use this setting in your embed when the in-app navigation between objects pushes multiple entries onto the host application's browser history stack. When set to `true`, this feature prevents users from getting trapped in back-button loops inside the embedded iframe. + +|[tag greenBackground]#NEW# a| + +[discrete] +===== Customization controls for Collections in full application embedding +The `HomeLeftNavItem.Collections` enum value is now available in the Visual Embed SDK. Embed developers can include *Collections* as a selectable navigation option in the embedded left navigation panel for full application embeds. When enabled, end users of the embedded application can navigate to *Collections* from the left navigation panel. + +For more information, see xref:full-app-customize.adoc[Customize full application embedding]. + +|[tag greenBackground]#MODIFIED# a| + +[discrete] +===== Lazy loading defaults for Liveboards +When `fullHeight` is enabled on `LiveboardEmbed` or `AppEmbed`, the following lazy-loading parameters now default to `true`: + +* `lazyLoadingForFullHeight` + +Enables lazy loading of visualizations when fullHeight is enabled. +* `enableScrollableContainerLazyLoading` + +Enables lazy loading for scrollable container elements. +* `lazyLoadingMargin` + +Sets the margin for lazy loading to `'500px 0px'`. + +These defaults apply automatically. Any value you set explicitly, including `false`, overrides the default. If `fullHeight` is disabled or not specified, the behavior is not affected. + +For more information, see xref:lazy-loading-fullheight.adoc[Full height and lazy loading options for Liveboards]. + +|[tag greenBackground]#NEW# a| + +[discrete] +===== Pre-render configuration object +The SDK introduces the `PreRenderConfig` interface, which bundles the existing prerender settings such as `preRenderId`, `preRenderContainer`, and `doNotTrackPreRenderSize` into a single object. + +The existing individual `preRenderId`, `preRenderContainer`, and `doNotTrackPreRenderSize` properties at the top-level are deprecated in this version. Update your integration to use the new `preRenderConfig` property on `BaseViewConfig` instead of the individual top-level properties. + +For more information, see xref:prerender.adoc[Pre-rendering ThoughtSpot embed components]. + +|[tag greenBackground]#NEW# +a| + +[discrete] +===== CSS customization + +CSS variable for unsaved filter indicator:: +A new CSS variable `--ts-var-unsaved-filter-indicator-color` is available to customize the color of the "unsaved changes" indicator dot shown on filter and parameter chips. + +Insight tile CSS variables:: +New CSS variables are available to customize the Liveboard insight tile appearance: + +* `--ts-var-liveboard-insight-tile-background` + +Background color of the insight tile. +* `--ts-var-liveboard-insight-tile-icon-color` + +Color of the insight tile icon. +* `--ts-var-liveboard-insight-tile-success-color` + +Color used for positive/success indicators. +* `--ts-var-liveboard-insight-tile-failure-color` + +Color used for negative/failure indicators. + +For more information, see xref:css-customization.adoc[CSS customization framework]. + +|| +|==== + +//// +|[tag greenBackground]#NEW# a| + + +[discrete] +===== Exported host-event contract types +The SDK now publicly exports host-event contract types that were previously internal-only. This allows TypeScript consumers to strongly type `embed.trigger(HostEvent.X, payload)` calls without importing internal modules. + +Newly exported types include: + +* `UIPassthroughContractBase`, `UIPassthroughRequest`, `UIPassthroughResponse`, `UIPassthroughArrayResponse` +* `HostEventRequest`, `HostEventResponse` +* `TriggerPayload`, `TriggerResponse` +* `LiveboardTab`, `LiveboardGroup` +* `Applicability`, `ApplicabilityLevel` +* `FilterUpdate`, `LiveboardFilter`, `LiveboardParameter` +* `SpotterAnalystConfig` +* `StarterPromptsConfig`, `StarterPromptCategory`, `StarterPreviewDataCategory`, `StarterPromptQuestion` +//// + == Version 1.51.x, August 2026 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| [discrete] ===== Spotter embedding Spotter Analysts:: -The Visual Embed SDK introduces controls for the Spotter Analysts feature in embedded applications. The Analysts section in the Spotter sidebar is disabled by default in the embed mode. For more information, see xref:customize-spotter-embed.adoc#_spotter_analysts[Spotter Analysts in embed view]. +The Visual Embed SDK introduces controls for the Spotter Analysts feature in embedded applications. The Analysts section in the Spotter sidebar is disabled by default in the embed mode. For more information, see xref:customize-spotter-analysts.adoc#_spotter_analysts[Spotter Analysts in embed view]. Starter prompts:: -If quick starter prompts are enabled and configured for data models on a ThoughtSpot instance, you can display these prompts in the embed using the `enableStarterPrompts` parameter. For more information, see xref:customize-spotter-embed.adoc#_spotter_starter_prompts[Spotter quick starter prompts]. +If quick starter prompts are enabled and configured for data models on a ThoughtSpot instance, you can display these prompts in the embed using the `enableStarterPrompts` parameter. For more information, see xref:customize-spotter-chat-experience.adoc#_spotter_starter_prompts[Spotter quick starter prompts]. |[tag greenBackground]#MODIFIED# a| @@ -42,34 +186,19 @@ Enables interactive filter chips that allow users to add, update, or remove filt For more information, see xref:embed-pinboard.adoc#common-customizations[Common customization options in Liveboard embedding]. -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| [discrete] ===== Object format support in HostEvent.Navigate The `HostEvent.Navigate` event now supports an object format in addition to the existing string path format. Use the object format to replace the current browser history entry instead of pushing a new entry. -//// -[source,JavaScript] ----- -// String format — push new history entry (existing behavior, unchanged) -appEmbed.trigger(HostEvent.Navigate, 'home'); ----- - -[source,JavaScript] ----- -// Object format — replace current history entry (new in SDK 1.51.0) -appEmbed.trigger(HostEvent.Navigate, { path: 'home', replace: true }); ----- -Supported embed types: `AppEmbed`. -//// - |==== == Version 1.50.x, July 2026 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| [discrete] ===== SpotterViz embed customization @@ -77,7 +206,7 @@ The Visual Embed SDK 1.50.0 introduces the `SpotterVizConfig` interface and `Spo A new `SpotterVizConfig` interface is available on `LiveboardViewConfig` and `AppViewConfig` for the `spotterViz` object. This object provides branding customization controls for customizing the SpotterViz panel experience. For more information, see xref:embed-spotterViz.adoc[SpotterViz in embedded Liveboards]. -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| [discrete] ===== Home page customization in full application embedding @@ -90,7 +219,7 @@ For more information, see xref:full-app-customize.adoc[Customize full applicatio [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| [discrete] ===== Visual overrides for charts and tables The SDK introduces the `visualOverrides` object in `SearchViewConfig` and @@ -107,7 +236,7 @@ The `visualOverrides` object provides the following customization controls to mo * `updateMaskPaths` property for partial updates. For more information, see xref:viz-overrides.adoc[Visualization overrides]. -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| [discrete] ===== Liveboard browser cache refresh @@ -124,7 +253,7 @@ Action ID to show or hide the cache refresh button. For more information, see xref:embed-pinboard.adoc#liveboard-data-cache[Enable Liveboard refresh]. -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| [discrete] ===== Spotter file upload The SDK introduces the following configuration parameters in `SpotterChatConfig` object to enable and control file uploads in the embedded Spotter chat interface. @@ -142,7 +271,7 @@ For more information, see xref:embed-spotter.adoc#fileUpload[Allowing file uploa == Version 1.48.x, May 2026 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| [discrete] ===== Liveboard embedding The SDK includes the following new features and enhancements in Liveboard embedding. @@ -181,7 +310,7 @@ Programmatically triggers the Send now action to send a test email notification * `Action.SendTestScheduleEmail` + Action ID to disable, show, or hide the **Send now** button on the Liveboard schedule page. -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| [discrete] ===== Spotter embedding @@ -195,7 +324,7 @@ For the connectors panel section in the Spotter chat interface. * `Action.SpotterChatModeSwitcher` + For the mode switcher in the Spotter chat interface. -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| [discrete] ===== Event handling @@ -215,7 +344,7 @@ host event has been updated to include a `type` discriminator field, making it consistent with the shape of other host event responses. It now returns `{ data: { v2Content }, type }` instead of `{ v2Content }` directly. This enhancement introduces a breaking change for any code that reads `result.v2Content` directly. Update your integration workflows to use `result.data.v2Content`. -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| [discrete] ===== Personalized View selection via host event @@ -242,7 +371,7 @@ The following events are deprecated and replaced with new event IDs. == Version 1.47.x, April 2026 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| **Spotter chat history sidebar customization** +|[tag greenBackground]#NEW# a| **Spotter chat history sidebar customization** The SDK introduces the `SpotterSidebarViewConfig` interface and the `spotterSidebarConfig` object with configuration controls to customize the appearance and contents of the chat history panel. Developers can use the following properties in the `spotterSidebarConfig` object to enable or disable chat history panel and customize the contents of the sidebar when enabled: @@ -297,7 +426,7 @@ spotterSidebarConfig: { } ---- -|[tag greenBackground]#NEW FEATURE# a| **Spotter chat UI branding** +|[tag greenBackground]#NEW# a| **Spotter chat UI branding** The SDK introduces the `SpotterChatViewConfig` interface for customizing branding in Spotter tool response cards. You can pass these parameters as the `spotterChatConfig` object properties in `SpotterEmbed`, `AppEmbed`, or `LiveboardEmbed` where Spotter interface is used. @@ -312,7 +441,7 @@ Custom label to replace the `ThoughtSpot` prefix in tool response cards. Set to These settings do not affect the external MCP tool branding. ==== -|[tag greenBackground]#NEW FEATURE# a|**Liveboard embed enhancements** +|[tag greenBackground]#NEW# a|**Liveboard embed enhancements** Personalized Liveboard view:: @@ -322,7 +451,7 @@ Centralized Liveboard filter setting:: When set to `true`, the `isCentralizedLiveboardFilterUXEnabled` enables displaying a unified modal to manage and update multiple filters at once, replacing the older individual filter interactions. This feature is disabled by default on ThoughtSpot Embedded instances. -|[tag greenBackground]#NEW FEATURE# a|**Option to include current period in rolling date filters** +|[tag greenBackground]#NEW# a|**Option to include current period in rolling date filters** If the current period inclusion in rolling date filters feature is enabled on your instance, the rolling date filters options such as **Last ** and **Next ** for the Liveboards and Answers in the embed view will allow you to include current period. For example, when you define a date range such as "Last 2 months", the date filter interface displays the **Include this month** checkbox. To disable this feature, use the `isThisPeriodInDateFiltersEnabled` setting. To hide, show, or disable this option in the embed view, use the action ID, `Action.IncludeCurrentPeriod`. @@ -333,7 +462,7 @@ To disable this feature, use the `isThisPeriodInDateFiltersEnabled` setting. To [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| **Host events with page context framework** +|[tag greenBackground]#NEW# a| **Host events with page context framework** The Visual Embed SDK introduces the HostEvent V2 framework for improved handling and execution of host events in embedded ThoughtSpot experiences with multi-layer UI interactions. The v2 framework supports the page context feature, which tracks the top-most active layer in the user's current context. Developers can use this feature to route events based on the user's current context or set a specific target context for precise and predictable handling of host events. @@ -347,7 +476,7 @@ For more information, refer to the xref:events-context-aware-routing.adoc[Host e 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** +|[tag greenBackground]#NEW# a| **Spotter experience** The SDK includes the following parameters, action IDs, and events to customize the Spotter embed experience. Chat history sidebar customization:: @@ -378,11 +507,11 @@ 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# | `enableLinkOverridesV2` + +|[tag greenBackground]#NEW# | `enableLinkOverridesV2` + Use this configuration setting 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** +|[tag greenBackground]#NEW# 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. @@ -392,7 +521,7 @@ Use this configuration setting to override ThoughtSpot URLs on hover or when ope [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| **Spotter enhancements** +|[tag greenBackground]#NEW# 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. @@ -413,7 +542,7 @@ Events:: 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** + +|[tag greenBackground]#NEW# a| **Liveboard experience enhancements** + Styling and grouping:: @@ -431,7 +560,7 @@ For more information, see link:https://docs.thoughtspot.com/cloud/latest/securit + The `showMaskedFilterChip` setting is also available in full application embedding. -|[tag greenBackground]#NEW FEATURE# a| **Publishing objects** +|[tag greenBackground]#NEW# a| **Publishing objects** The following action IDs are available for the data publishing menu actions in the *Data workspace* page: @@ -439,7 +568,7 @@ The following action IDs are available for the data publishing menu actions in t * `Action.ManagePublishing` for *Manage publishing* * `Action.Unpublish` for *Unpublish* * `Action.Parameterize` for *Parameterize* -|[tag greenBackground]#NEW FEATURE# a| **Error handling improvements** +|[tag greenBackground]#NEW# a| **Error handling improvements** To handle errors in the embedding workflows, the SDK includes the following features: @@ -460,7 +589,7 @@ For more information, see link:https://developers.thoughtspot.com/docs/Enumerati 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. -|[tag greenBackground]#NEW FEATURE# a| *Intercepting API calls* + +|[tag greenBackground]#NEW# a| *Intercepting API calls* + The SDK provides the following attributes to intercept API calls and handle interception via events and custom workflows: //* `enableApiIntercept` + @@ -481,7 +610,7 @@ For more information, see xref:api-intercept.adoc[Intercept API calls and search == Version 1.43.0, November 2025 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| *Code-based custom actions* +|[tag greenBackground]#NEW# a| *Code-based custom actions* The following enumerations are available for code-based custom actions: @@ -489,7 +618,7 @@ The following enumerations are available for code-based custom actions: To define the target object for the custom action, such as on a Liveboard, visualization, Answer, or in Spotter. * `CustomActionsPosition` + To define the position of the custom action in the target object, such as primary menu, **More** options menu image:./images/icon-more-10px.png[the more options menu], or the contextual menu. -|[tag greenBackground]#NEW FEATURE# | *Attribute to set Parameter chip visibility during overrides* + +|[tag greenBackground]#NEW# | *Attribute to set Parameter chip visibility during overrides* + The `HostEvent.UpdateParameters` event now supports configuring the `isVisibleToUser` attribute to show or hide the Parameter chips after an override. For more information, see xref:runtime-parameters.adoc#_show_or_hide_parameter_chips_in_embedded_sessions[Show or hide Parameter chips in embedded sessions]. |==== @@ -497,14 +626,14 @@ The `HostEvent.UpdateParameters` event now supports configuring the `isVisibleTo [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a|*Runtime overrides in Spotter embed* +|[tag greenBackground]#NEW# a|*Runtime overrides in Spotter embed* The Visual Embed SDK now supports runtime overrides in Spotter embed. * To apply runtime filters, use the `runtimeFilters` object * To apply runtime Parameters, use the `runtimeParameters` object. -|[tag greenBackground]#NEW FEATURE# a|*PNG images in Liveboard schedule notifications* + +|[tag greenBackground]#NEW# a|*PNG images in Liveboard schedule notifications* + To enable embedding PNG images of Liveboards in scheduled job notifications sent to subscribers, the SDK provides the `isPNGInScheduledEmailsEnabled` boolean parameter. When set to true, scheduled emails will include a PNG image of the Liveboard. The SDK also provides the following action IDs: @@ -513,7 +642,7 @@ The SDK also provides the following action IDs: Adds the option to include a PNG screenshot in the notification email body when scheduling emails in ThoughtSpot. * `Action.RemoveAttachment` + Allows the user to remove an attachment from the email configuration in the schedule email dialog. -|[tag greenBackground]#NEW FEATURE# a|*Spotter embed* +|[tag greenBackground]#NEW# a|*Spotter embed* Action IDs:: The following action IDs are available for Spotter embedding and are currently supported only in the `hiddenActions` array: @@ -530,13 +659,13 @@ Action ID to enable or disable the link:https://docs.thoughtspot.com/cloud/lates [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a|*React component for Spotter Agent embed* +|[tag greenBackground]#NEW# a|*React component for Spotter Agent embed* The Visual Embed SDK now supports embedding Spotter Agent feature without a body or Spotter interface in a React app. For ease of implementation, the SDK also provides a custom React hook, `useSpotterAgent`. For more information, see xref:embed-ts-react-app.adoc#_embed_spotter_agent_in_your_own_app[Spotter Agent embedding in a React app]. -|[tag greenBackground]#NEW FEATURE# a|*Event handlers for Spotter embed* +|[tag greenBackground]#NEW# a|*Event handlers for Spotter embed* The following event handlers are now available for Spotter embed: @@ -555,7 +684,7 @@ Triggers the action to get TML representation of a Spotter-generated Answer. For more information, see xref:EmbedEvent.adoc[EmbedEvent] and xref:HostEvent.adoc[HostEvent]. -|[tag greenBackground]#NEW FEATURE# a|*Event handlers for Spotter Agent embed* +|[tag greenBackground]#NEW# a|*Event handlers for Spotter Agent embed* You can now use the following host events in Spotter Agent embedding: @@ -574,7 +703,7 @@ Triggers the *Save* action for a Spotter-generated Answer. For more information, see xref:HostEvent.adoc[HostEvent]. -|[tag greenBackground]#NEW FEATURE# a| *Lazy loading of visualizations on an embedded Liveboard* +|[tag greenBackground]#NEW# a| *Lazy loading of visualizations on an embedded Liveboard* You can now use the `lazyLoadingForFullHeight` parameter with the `fullHeight` to progressively load visualizations on an embedded Liveboard. When both these attributes are enabled, only the visualizations in the current viewport are loaded initially, while the other visualizations load as the user scrolls the Liveboard page. @@ -582,7 +711,7 @@ You can also set the margin property for lazy loading to define when the visuali For more information, see xref:lazy-loading-fullheight.adoc[Lazy loading of visualizations in an embedded Liveboard]. -|[tag greenBackground]#NEW FEATURE# a| *Full application embed* + +|[tag greenBackground]#NEW# a| *Full application embed* + You can now enable the persona-based left navigation panel and home page experience on your ThoughtSpot instance. This feature is disabled by default on ThoughtSpot instances and is available for Early Access. When it's enabled on your ThoughtSpot instance, you can roll out the new experience on embedding applications by configuring the xref:AppViewConfig.adoc#_discoveryexperience[`discoveryExperience`] attribute. @@ -593,22 +722,22 @@ When enabled, the left navigation panel organizes the application menu into pers [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| *Fullscreen presentation mode controls for embedded Liveboards and visualizations* + +|[tag greenBackground]#NEW# a| *Fullscreen presentation mode controls for embedded Liveboards and visualizations* + Developers can now control whether a visualization or Liveboard can be presented in full screen mode using the `disableFullscreenPresentation` attribute. By default, the full screen mode is disabled on embedded Liveboards and visualizations. -|[tag greenBackground]#NEW FEATURE# a| *PDF download settings* + +|[tag greenBackground]#NEW# a| *PDF download settings* + Developers can now control the display of *Include cover page* and *Include filter page(s)* options on the Download PDF dialog for Liveboards. The *Include cover page* and *Include filter page(s)* options are disabled by default on ThoughtSpot instances. When this feature is enabled, developers can use the `coverAndFilterOptionInPDF` attribute to show or hide these options for the Liveboard users in their embedding app. -|[tag greenBackground]#NEW FEATURE# a| *Parameter for overriding a default primary action* + +|[tag greenBackground]#NEW# a| *Parameter for overriding a default primary action* + If Spotter is enabled on your instance, the *Spotter* button appears by default as the primary action on embedded Liveboard charts; if Spotter is not enabled, the *Explore* button is set as the primary action. If you want to replace the primary action with a different action, you can now use the `primaryAction` attribute. For more information, see xref:embed-actions.adoc#_override_default_primary_actions[Override default primary action]. -|[tag greenBackground]#NEW FEATURE# a| *Full application embed experience enhancements* + +|[tag greenBackground]#NEW# a| *Full application embed experience enhancements* + The SDK now includes the `hideObjectSearch` property, which allows developers to hide the object search button in the navigation bar when embedding the full application. -|[tag greenBackground]#NEW FEATURE# a| *Host events* + +|[tag greenBackground]#NEW# a| *Host events* + In this version, the SDK introduces the following host event handlers: @@ -627,7 +756,7 @@ Triggers the delete prompt action. For more information, see xref:HostEvent.adoc[HostEvent]. -|[tag greenBackground]#NEW FEATURE# a|*Events support for Spotter embed* +|[tag greenBackground]#NEW# a|*Events support for Spotter embed* You can now use the following host events in Spotter embed: @@ -643,7 +772,7 @@ You can now use the following host events in Spotter embed: For more information, see xref:HostEvent.adoc[HostEvent]. -|[tag greenBackground]#NEW FEATURE# a| *Lazy loading with full height* +|[tag greenBackground]#NEW# a| *Lazy loading with full height* The SDK introduces `lazyLoadingForFullHeight` parameter, which enables progressive loading of visualizations on an embedded Liveboard. This parameter works in conjunction with the `fullHeight` attribute. When both these attributes are enabled, only the visualizations in the current viewport are loaded initially, while the other visualizations load as the user scrolls the Liveboard page. @@ -659,7 +788,7 @@ To use these attributes effectively in embedded applications, your ThoughtSpot i [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| *Spotter embed components with new names* + +|[tag greenBackground]#NEW# a| *Spotter embed components with new names* + The following Spotter embed components are now deprecated and replaced with new components in the SDK and Visual Embed Playground: * `ConversationEmbed` + @@ -673,13 +802,13 @@ Replaced with `SpotterAgentEmbedViewConfig` The deprecated components with old names in the existing Spotter embed implementations will continue to function until further notice. For code samples with new component names, see xref:embed-spotter.adoc[Spotter embed documentation]. -|[tag greenBackground]#NEW FEATURE# a| *Action ID for Spotter in-conversation training* + +|[tag greenBackground]#NEW# a| *Action ID for Spotter in-conversation training* + For ThoughtSpot instances that have the new Spotter in-conversation training workflow enabled, the SDK provides the action ID `Action.InConversationTraining` to manage the visibility of the *Add to Coaching* button on Answers generated from Spotter prompts. [NOTE] The *Add to Coaching* feature is currently in beta and is turned off by default on embed deployments. To enable this feature on your instance, contact ThoughtSpot Support. -|[tag greenBackground]#NEW FEATURE# a|*Events support for Spotter embed* +|[tag greenBackground]#NEW# a|*Events support for Spotter embed* New embed events:: @@ -733,7 +862,7 @@ For more information, see xref:EmbedEvent.adoc[EmbedEvent]. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| *String IDs for text customization* + +|[tag greenBackground]#NEW# a| *String IDs for text customization* + Developers can now customize a specific occurrence of a visible text string in the ThoughtSpot UI using the `stringIDs` object in the customization interface. To locate the string IDs, SDK provides the `exposeTranslationIds` attribute. By setting `exposeTranslationIds` to `true` in the Playground, you can find the string ID of the UI text and use it in your customization code. @@ -742,7 +871,7 @@ Additionally, the SDK provides the `StringIDsUrl` attribute to allow using a JSO For more information, see xref:customize-text-strings.adoc[Customize text strings]. -|[tag greenBackground]#NEW FEATURE# a| *Hide columns on list pages* + +|[tag greenBackground]#NEW# a| *Hide columns on list pages* + In full app embedding, you can now hide the following columns on the *Liveboards* and *Answers* listing pages using the `hiddenListColumns` array: @@ -764,16 +893,16 @@ For more information, see xref:full-app-customize.adoc#_hide_columns_on_list_pag [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| The SDK now provides the `customVariablesForThirdPartyTools` setting to pass custom variables when integrating third-party tools and running custom scripts in your embed. Developers can define this object in the **init()** function and add variables as key-value pairs. This feature is available only if third-party integration is enabled on your instance and the script hosting domain URL is added to the CSP allowlist. For more information, see xref:3rd-party-script.adoc[Integrate third-party tools and allow custom scripts]. -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| You can now exclude search token string from the application URL by setting `excludeSearchTokenStringFromURL` to `true` in your embed with ThoughtSpot token-based Search or Search bar. -|[tag greenBackground]#NEW FEATURE# a| This version of the SDK supports the following embed and host events: +|[tag greenBackground]#NEW# a| This version of the SDK supports the following embed and host events: Embed Events:: @@ -796,7 +925,7 @@ Triggers the *Delete* action on a Liveboard. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| The following HostEvents now allow custom parameters to set object properties programmatically: * `HostEvent.SaveAnswer` + @@ -806,7 +935,7 @@ Allows adding custom properties for visualization ID, name, and description, Liv For more information, see xref:events-hostEvents.adoc#hostEventParameterization[Host Events] documentation. -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| New configuration attributes:: @@ -848,7 +977,7 @@ The following new CSS variables are available for Spotter interface customizatio * `--ts-var-spotter-prompt-background` For more information about Spotter customization, see xref:embed-spotter.adoc#SpotterCSS[Customize styles]. -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| Configuration attributes:: @@ -872,7 +1001,7 @@ ID for the action that disables filter chip reordering. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| +|[tag greenBackground]#NEW# a| The SDK now provides the `isUnifiedSearchExperienceEnabled` setting to customize the Search experience on ThoughtSpot Home page for embedding application users: * When set to `true`, the split search experience is disabled and the Search bar on the Home page functions as Natural Language Search interface @@ -880,14 +1009,14 @@ The SDK now provides the `isUnifiedSearchExperienceEnabled` setting to customize For more information, see xref:full-app-customize.adoc#_search_components[Search interface on the Home page in full application embedding]. -|[tag greenBackground]#NEW FEATURE# a| The `overrideOrgId` parameter in the SDK provides the ability to override Org context for embedding application users. This parameter allows users authenticated to an Org to temporarily view content from another Org. Before specifying the Org ID for override, make sure the Per Org URL feature is enabled on your ThoughtSpot instance. To enable Per Org URL on your instance, contact ThoughtSpot Support. +|[tag greenBackground]#NEW# a| The `overrideOrgId` parameter in the SDK provides the ability to override Org context for embedding application users. This parameter allows users authenticated to an Org to temporarily view content from another Org. Before specifying the Org ID for override, make sure the Per Org URL feature is enabled on your ThoughtSpot instance. To enable Per Org URL on your instance, contact ThoughtSpot Support. |==== == Version 1.34.0, November 2024 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| You can now embed the following ThoughtSpot Spotter components in your app: +|[tag greenBackground]#NEW# a| You can now embed the following ThoughtSpot Spotter components in your app: * `SpotterEmbed` + Embeds Spotter conversation interface in your app @@ -896,7 +1025,7 @@ Creates a conversation component without the body, which can be integrated into For more information, see xref:embed-spotter.adoc[Embed Spotter] and xref:spotter-in-custom-chatbot.adoc[Integrate Spotter into your chatbot]. -|[tag greenBackground]#NEW FEATURE# a|The following parameters and enumerations are available for customizing Liveboard experience: +|[tag greenBackground]#NEW# a|The following parameters and enumerations are available for customizing Liveboard experience: * `showLiveboardVerifiedBadge` + Shows or hides the Liveboard verified badge. Available if the Liveboard compact header feature is enabled. @@ -905,16 +1034,16 @@ Shows or hides the re-verify banner. Available if the Liveboard compact header f * `Action.KPIAnalysisCTA` + Action ID to show, hide, or disable the **Analyze CTA** action on a KPI chart. -|[tag greenBackground]#NEW FEATURE# |You can now use the `HostEvent.GetIframeUrl` to get the iframe src URL from the Visual Embed Playground. If you are embedding ThoughtSpot in apps like Salesforce and Sharepoint without the SDK, use this event to generate the iframe URL. +|[tag greenBackground]#NEW# |You can now use the `HostEvent.GetIframeUrl` to get the iframe src URL from the Visual Embed Playground. If you are embedding ThoughtSpot in apps like Salesforce and Sharepoint without the SDK, use this event to generate the iframe URL. -|[tag greenBackground]#NEW FEATURE# a|The following parameters are available for customizing Search experience: +|[tag greenBackground]#NEW# a|The following parameters are available for customizing Search experience: * `collapseDataPanel` Minimizes the data panel view. Users can click the data panel header any time to expand the panel. * `collapseSearchBar` Sets the initial state of the search bar when embedding a saved Answer. -|[tag greenBackground]#NEW FEATURE# a| The following settings are available for customizing the new home page and navigation experience in full app embedding: +|[tag greenBackground]#NEW# a| The following settings are available for customizing the new home page and navigation experience in full app embedding: * `HomeLeftNavItem.LiveboardSchedules` + The Liveboard schedules menu on the left navigation panel. @@ -937,7 +1066,7 @@ To show, disable, or hide the *Unsubscribe* action on the *Liveboard schedules* [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| You can now customize the search experience for the embedded ThoughtSpot **Home** page using `homePageSearchBarMode`. By default, the **Home** page includes the Object Search bar, which allows finding popular Liveboards and Answers. +|[tag greenBackground]#NEW# a| You can now customize the search experience for the embedded ThoughtSpot **Home** page using `homePageSearchBarMode`. By default, the **Home** page includes the Object Search bar, which allows finding popular Liveboards and Answers. You can set the `homePageSearchBarMode` property to one of the following options: @@ -947,8 +1076,8 @@ Displays the search bar for Natural Language Search. Hides the Search bar on the **Home** page. Note that it only hides the Search bar on the **Home** page and doesn't affect the Object Search bar visibility on the top navigation bar. ** `objectSearch` (default) + Displays Object Search bar on the **Home** page. -|[tag greenBackground]#NEW FEATURE# a|The SDK now allows you to set the focus on the Search bar or outside the Search bar when rendering the embedded Search page. Use the `focusSearchBarOnRender` property to set the position of the cursor focus. -|[tag greenBackground]#NEW FEATURE# a| The SDK includes the following Event and Action enumeration members: +|[tag greenBackground]#NEW# a|The SDK now allows you to set the focus on the Search bar or outside the Search bar when rendering the embedded Search page. Use the `focusSearchBarOnRender` property to set the position of the cursor focus. +|[tag greenBackground]#NEW# a| The SDK includes the following Event and Action enumeration members: Events:: @@ -968,7 +1097,7 @@ Use this action enumeration to disable, show, or hide the **Manage tags** button [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| The following new action enumerations are available in this version: + +|[tag greenBackground]#NEW# a| The following new action enumerations are available in this version: + * `Action.CreateLiveboard` for the *Create Liveboard* menu action on the Liveboards lists page. + * `Action.SyncToTeams` for the **Sync to Teams** menu action on Liveboard visualizations. @@ -978,26 +1107,26 @@ Use this action enumeration to disable, show, or hide the **Manage tags** button * `Action.AddDataPanelObjects` for the **Add** menu that includes sub-menu options such as Formulas, Parameters, Query set, and Column set actions. * `Action.OrganiseFavourites` for the **Organize** action above the Favorites panel on the modular Homepage (New experience) For more information, see xref:Action.adoc[Actions]. -|[tag greenBackground]#NEW FEATURE#| Developers can now use the `disableRedirectionLinksInNewTab` parameter to disable links and redirection of links in the embedded view. -|[tag greenBackground]#NEW FEATURE# a|You can now enable `enable2ColumnLayout` on a Liveboard to adjust the page view according to the width and resolution of users' devices. +|[tag greenBackground]#NEW#| Developers can now use the `disableRedirectionLinksInNewTab` parameter to disable links and redirection of links in the embedded view. +|[tag greenBackground]#NEW# a|You can now enable `enable2ColumnLayout` on a Liveboard to adjust the page view according to the width and resolution of users' devices. || |==== == Version 1.31.x, July 2024 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| Runtime filters + +|[tag greenBackground]#NEW# a| Runtime filters + * `NOT_IN` operator for Runtime filters. For more information, see xref:runtime-filters.adoc#runtimeFilterOp[Runtime filters]. * `excludeRuntimeParametersfromURL` parameter to exclude or remove runtimeParameters from the URL. -|[tag greenBackground]#NEW FEATURE# |For performance optimization, developers can choose to load embedded views in a lightweight V2 shell by setting `enableV2Shell_experimental` to `true`. +|[tag greenBackground]#NEW# |For performance optimization, developers can choose to load embedded views in a lightweight V2 shell by setting `enableV2Shell_experimental` to `true`. |==== == Version 1.30.0, June 2024 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| **CSS variables for new homepage experience** +|[tag greenBackground]#NEW# a| **CSS variables for new homepage experience** * `--ts-var-home-watchlist-selected-text-color` + * `--ts-var-home-card-color` + @@ -1012,7 +1141,7 @@ For more information, see xref:css-customization.adoc#_homepage_modules_new_expe [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| **Ask Sage** +|[tag greenBackground]#NEW# a| **Ask Sage** With Ask Sage [beta betaBackground]^Beta^ embedded application users can ask follow-up questions on a visualization generated from a Natural Language Search query, converse with AI analyst, and refine results. To enable this feature, set `enableAskSage` to `true`. @@ -1043,11 +1172,11 @@ Updates cross filters applied on a Liveboard. [width="100%" cols="1,4"] |===== -|[tag greenBackground]#NEW FEATURE# a| The SDK includes the following new enumeration members in v1.28.0: +|[tag greenBackground]#NEW# a| The SDK includes the following new enumeration members in v1.28.0: ** `Action.VerifiedLiveboard` + Can be used to show or hide the *Verified Liveboard* banner. -|[tag greenBackground]#NEW FEATURE# a| To access the new Home page and global navigation experience in the full application embedding, you can use the `modularHomeExperience` property in the SDK. The modular homepage experience is turned off by default and is available as an Early Access feature in 9.12.5.cl release. When `modularHomeExperience` is set to `true`, you can use the following parameters in the SDK to control the application experience: +|[tag greenBackground]#NEW# a| To access the new Home page and global navigation experience in the full application embedding, you can use the `modularHomeExperience` property in the SDK. The modular homepage experience is turned off by default and is available as an Early Access feature in 9.12.5.cl release. When `modularHomeExperience` is set to `true`, you can use the following parameters in the SDK to control the application experience: * `hiddenhomeleftnavitems` * `hiddenhomepagemodules` @@ -1058,11 +1187,11 @@ Can be used to show or hide the *Verified Liveboard* banner. * `HomeLeftNavItem` For more information, see xref:full-app-customize.adoc[Customize full application embedding] and xref:AppViewConfig.adoc[AppViewConfig]. -|[tag greenBackground]#NEW FEATURE# a| The following embed event is available from the v1.28.0 onwards: +|[tag greenBackground]#NEW# a| The following embed event is available from the v1.28.0 onwards: `EmbedEvent.Rename` + Emits when an embedded Liveboard or visualization is renamed. -|[tag greenBackground]#NEW FEATURE# a| TML actions +|[tag greenBackground]#NEW# a| TML actions The following TML menu actions are now grouped under the **TML** sub-menu of the **More** image:./images/icon-more-10px.png[the more options menu] menu on Answer page. @@ -1089,10 +1218,10 @@ hiddenActions: [Action.TML] // to disable all TML actions disabledActions: [Action.TML] ---- -|[tag greenBackground]#NEW FEATURE# | You can now reset authentication token and fetch a new token for new authentication requests. +|[tag greenBackground]#NEW# | You can now reset authentication token and fetch a new token for new authentication requests. For more information, see link:https://developers.thoughtspot.com/docs/Function_resetCachedAuthToken[resetCachedAuthToken]. -|[tag greenBackground]#NEW FEATURE#| You can now override the default number, date, and currency format defined by your locale settings. To override the default settings, use the following parameters: +|[tag greenBackground]#NEW#| You can now override the default number, date, and currency format defined by your locale settings. To override the default settings, use the following parameters: * `numberFormatLocale` + * `dateFormatLocale` + @@ -1100,7 +1229,7 @@ For more information, see link:https://developers.thoughtspot.com/docs/Function_ For more information, see xref:locale-setting.adoc#_set_locale_in_the_sdk[Customize locale]. -|[tag greenBackground]#NEW FEATURE# |Tokenized fetch + +|[tag greenBackground]#NEW# |Tokenized fetch + The SDK now provides a fetch wrapper that adds the authentication token to the API requests. For more information, see link:https://developers.thoughtspot.com/docs/Function_tokenizedFetch#_tokenizedfetch[tokenizedFetch]. |===== @@ -1109,7 +1238,7 @@ For more information, see link:https://developers.thoughtspot.com/docs/Function_ [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| The following action enumeration members are available from v1.27.9 and v1.27.10: +|[tag greenBackground]#NEW# a| The following action enumeration members are available from v1.27.9 and v1.27.10: * `Action.AIHighlights` * `Action.AddToWatchlist` @@ -1117,23 +1246,23 @@ For more information, see link:https://developers.thoughtspot.com/docs/Function_ * `Action.CopyKpiLink` For more information, see xref:Action.adoc[Action]. -| [tag greenBackground]#NEW FEATURE# a| You can now use `HostEvent.GetAnswerSession` to get Answer session data for a Search Answer or Liveboard Visualization in the embedded view. +| [tag greenBackground]#NEW# a| You can now use `HostEvent.GetAnswerSession` to get Answer session data for a Search Answer or Liveboard Visualization in the embedded view. |==== == Version 1.27.0, January 2024 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a|The `SageEmbed` package is now available on all clusters. You can use this SDK package to embed Natural Language Search capabilities and assist users with AI-suggested queries and AI-generated answers. This SDK package also allows you to customize the Natural Language Search experience in the embedded view. - -For a complete list of methods, functions, interface objects, and properties, see the following pages: + +|[tag greenBackground]#NEW# a|The `SageEmbed` package is now available on all clusters. You can use this SDK package to embed Natural Language Search capabilities and assist users with AI-suggested queries and AI-generated answers. This SDK package also allows you to customize the Natural Language Search experience in the embedded view. -* xref:SageEmbed.adoc[SageEmbed] -* xref:SageViewConfig.adoc[SageViewConfig] +//For a complete list of methods, functions, interface objects, and properties, see the following pages: + +// +//* xref:SageEmbed.adoc[SageEmbed] +//* xref:SageViewConfig.adoc[SageViewConfig] |[tag orangeBackground]#MODIFIED# a| The `HostEvent.DrillDown` now supports the `vizId` parameter to trigger a drill-down action on a specific visualization of a Liveboard. For more information, see xref:HostEvent.adoc#_drilldown[DrillDown]. -|[tag greenBackground]#NEW FEATURE# a| The new version of the SDK introduces the following new enumeration members: +|[tag greenBackground]#NEW# a| The new version of the SDK introduces the following new enumeration members: * Host Events ** `HostEvent.UpdateSageQuery` + @@ -1149,10 +1278,10 @@ Emitted when a user creates a new Worksheet. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| The SDK provides `AnswerService` class to trigger the answer service with a custom action payload. +|[tag greenBackground]#NEW# a| The SDK provides `AnswerService` class to trigger the answer service with a custom action payload. You can use this service to run GraphQL queries in the context of the Answer with a custom action trigger. For more information, see link:https://developers.thoughtspot.com/docs/Class_AnswerService[AnswerService]. Recommended ThoughtSpot application version is 9.10.0.cl. -|[tag greenBackground]#NEW FEATURE# a|The following object properties and feature flags are introduced in the `LiveboardEmbed` and `AppEmbed` SDK packages: +|[tag greenBackground]#NEW# a|The following object properties and feature flags are introduced in the `LiveboardEmbed` and `AppEmbed` SDK packages: * `showLiveboardDescription` + Shows the Liveboard description text when set to `true` @@ -1167,9 +1296,9 @@ Hides the specified tabs from the Liveboard page * `visibleTabs` + Displays the specified tabs on the Liveboard page -|[tag greenBackground]#NEW FEATURE# |You can now enable the new data panel experience by setting `dataPanelV2` to `true` in the SDK when embedding ThoughtSpot Search. The new data panel experience is turned off by default on embedded ThoughtSpot instances. +|[tag greenBackground]#NEW# |You can now enable the new data panel experience by setting `dataPanelV2` to `true` in the SDK when embedding ThoughtSpot Search. The new data panel experience is turned off by default on embedded ThoughtSpot instances. -|[tag greenBackground]#NEW FEATURE# a|The new version of the SDK supports the following events: +|[tag greenBackground]#NEW# a|The new version of the SDK supports the following events: Embed events:: * `EmbedEvent.hiddenTabs` @@ -1193,7 +1322,7 @@ Host events:: + For more information, see xref:HostEvent.adoc[HostEvent]. -|[tag greenBackground]#NEW FEATURE# a| The SDK introduces the following action enumeration members: +|[tag greenBackground]#NEW# a| The SDK introduces the following action enumeration members: * `Action.AddTab` + Show, disable, or hide the **Add Tab** action on a Liveboard. @@ -1213,10 +1342,10 @@ For more information, see xref:Action.adoc[Actions]. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# | The SDK now supports runtime Parameter overrides on Liveboards and Answers. +|[tag greenBackground]#NEW# | The SDK now supports runtime Parameter overrides on Liveboards and Answers. For more information, see xref:runtime-parameters.adoc#_apply_parameter_overrides_using_visual_embed_sdk[Runtime Parameter overrides]. -|[tag greenBackground]#NEW FEATURE# a| The SDK introduces the following action enumeration members: +|[tag greenBackground]#NEW# a| The SDK introduces the following action enumeration members: * `Action.RenameModalTitleDescription` * `Action.EnableContextualChangeAnalysis` @@ -1230,22 +1359,22 @@ For more information, see xref:Action.adoc[Actions]. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| ThoughtSpot now provides the `SageEmbed` package to embed the ThoughtSpot Search page with Sage features such as natural language search and AI-suggested search examples. This feature is in beta and not available in the Visual Embed Playground. -|[tag greenBackground]#NEW FEATURE# a| The `HostEvent.SetActiveTab` event in the upcoming version of the SDK allows you to set a tab as an active tab on a Liveboard. +|[tag greenBackground]#NEW# a| ThoughtSpot now provides the `SageEmbed` package to embed the ThoughtSpot Search page with Sage features such as natural language search and AI-suggested search examples. This feature is in beta and not available in the Visual Embed Playground. +|[tag greenBackground]#NEW# a| The `HostEvent.SetActiveTab` event in the upcoming version of the SDK allows you to set a tab as an active tab on a Liveboard. |==== == Version 1.23.0, August 2023 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| The SDK supports the following performance optimization enhancements: + +|[tag greenBackground]#NEW# a| The SDK supports the following performance optimization enhancements: + * Ability to pre-render a generic instance of the ThoughtSpot component using the `prerenderGeneric` attribute. The generic instance uses the default host and flags and can be rendered in the background to improve application response. * Ability to use an iFrame from a pre-rendered iFrame pool using the `usePrerenderedIfAvailable` attribute. |==== //// -|[tag greenBackground]#NEW FEATURE# a| New events for Liveboard filters + +|[tag greenBackground]#NEW# a| New events for Liveboard filters + * `EmbedEvent.FilterChanged` + * `HostEvent.GetFilters` + @@ -1256,18 +1385,18 @@ For more information, see xref:Action.adoc[Actions]. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| The new version of the SDK introduces the `TrustedAuthTokenCookieless` `authType` property to allow Cookieless embedding. The Cookieless authentication method allows using a bearer token to identify the signed-in user instead of session cookies. +|[tag greenBackground]#NEW# a| The new version of the SDK introduces the `TrustedAuthTokenCookieless` `authType` property to allow Cookieless embedding. The Cookieless authentication method allows using a bearer token to identify the signed-in user instead of session cookies. For more information, see xref:embed-authentication.adoc#_cookieless_authentication[Cookieless authentication]. -|[tag greenBackground]#NEW FEATURE# a|The new version of the SDK allows you to block user access to the non-embedded instance of the ThoughtSpot application. In full app embed deployments, you can use the `blockNonEmbedFullAppAccess` property in the SDK to restrict or allow your application users from accessing ThoughtSpot pages in the non-embed mode. +|[tag greenBackground]#NEW# a|The new version of the SDK allows you to block user access to the non-embedded instance of the ThoughtSpot application. In full app embed deployments, you can use the `blockNonEmbedFullAppAccess` property in the SDK to restrict or allow your application users from accessing ThoughtSpot pages in the non-embed mode. For more information, see xref:security-settings.adoc#_block_access_to_non_embedded_thoughtspot_pages[Block access to non-embedded ThoughtSpot pages]. |==== //// -|[tag greenBackground]#NEW FEATURE# a| The SDK supports the following performance optimization enhancements: + +|[tag greenBackground]#NEW# a| The SDK supports the following performance optimization enhancements: + * Ability to pre-render a generic instance of the ThoughtSpot component using the `prerenderGeneric` attribute. The generic instance uses the default host and flags and can be rendered in the background to improve application response. * Ability to use an iFrame from a pre-rendered iFrame pool using the `usePrerenderedIfAvailable` attribute. @@ -1276,7 +1405,7 @@ For more information, see xref:security-settings.adoc#_block_access_to_non_embed == Version 1.21.0, May 2023 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a|The new version of the SDK introduces the following action enumeration members: +|[tag greenBackground]#NEW# a|The new version of the SDK introduces the following action enumeration members: * `Action.AxisMenuAggregate` * `Action.AxisMenuConditionalFormat` @@ -1295,7 +1424,7 @@ For more information, see xref:security-settings.adoc#_block_access_to_non_embed For more information, see xref:embed-action-ref.adoc[Action reference]. -|[tag greenBackground]#NEW FEATURE# a| The SDK introduces the following events: +|[tag greenBackground]#NEW# a| The SDK introduces the following events: * `HostEvent.AddColumns` * `HostEvent.OpenFilter` @@ -1336,7 +1465,7 @@ To disable or hide download actions, you can use `Action.Download` in the `disab ** `Action.DownloadAsXlsx` + ** `Action.DownloadAsPng` -|[tag greenBackground]#NEW FEATURE# a| The SDK includes new attributes to customize the experience for embedded app users: +|[tag greenBackground]#NEW# a| The SDK includes new attributes to customize the experience for embedded app users: * `linkOverride` + @@ -1349,7 +1478,7 @@ Allows triggering contextual menu on the Liveboard visualizations and Answers fr * `hideSearchBar` + Allows hiding the Search bar on the embedded Search page. -|[tag greenBackground]#NEW FEATURE# | The SDK now allows setting the loading preference for embedded iFrames. +|[tag greenBackground]#NEW# | The SDK now allows setting the loading preference for embedded iFrames. For performance optimization, you can set the `loading` attribute to `lazy` in the `FrameParams` property. |==== @@ -1358,14 +1487,14 @@ For performance optimization, you can set the `loading` attribute to `lazy` in t [width="100%" cols="1,4"] |==== |[tag redBackground]#DEPRECATED# a|The `dataSources` property in `SearchEmbed` and `SearchBarEmbed` is deprecated and replaced with the `dataSource` attribute. The SDK supports searching from a single data source only. -|[tag greenBackground]#NEW FEATURE# a|The embed SDK packages now include the `insertAsSibling` property. This attribute can be used to insert the embedded object as a sibling to the element inside the target container. +|[tag greenBackground]#NEW# a|The embed SDK packages now include the `insertAsSibling` property. This attribute can be used to insert the embedded object as a sibling to the element inside the target container. |==== == Version 1.19.0, February 2023 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a|The `customCSS` property in the `customizations` object supports new variables to customize the styles for dialogs, search bar, search navigation and search suggestions panels. +|[tag greenBackground]#NEW# a|The `customCSS` property in the `customizations` object supports new variables to customize the styles for dialogs, search bar, search navigation and search suggestions panels. For more information, see xref:css-customization.adoc[Customize CSS]. |[tag redBackground]#BREAKING CHANGE# a|The new Liveboard experience mode introduces changes to the data format of the JSON response payload triggered by callback custom actions. For example, the `reportBookData`, and `vizData` attributes are modified, and the custom action `id` now is part of the data attribute. These changes may break your current custom action event handlers. For interoperability, we recommend adding the data attribute to `payload` in your code as shown in the example here: @@ -1380,7 +1509,7 @@ liveboardEmbed.on(EmbedEvent.CustomAction, payload => { You may also want to update the data classes in your scripts to process the JSON response payload and handle complex data. For more information, see xref:custom-actions-callback.adoc#_define_functions_and_classes_to_handle_liveboard_data[Callback custom actions]. -|[tag greenBackground]#NEW FEATURE# a|The new version of the SDK introduces the following Host events: +|[tag greenBackground]#NEW# a|The new version of the SDK introduces the following Host events: * `HostEvent.Delete` * `HostEvent.Download` @@ -1405,17 +1534,17 @@ For more information, see xref:embed-authentication.adoc#_saml_redirection[SAML [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a|The new version of the SDK provides the `SearchBarEmbed` JavaScript package to embed only the ThoughtSpot Search bar in your app. + +|[tag greenBackground]#NEW# a|The new version of the SDK provides the `SearchBarEmbed` JavaScript package to embed only the ThoughtSpot Search bar in your app. + For more information, see xref:embed-searchbar.adoc[Embed ThoughtSpot search bar]. -|[tag greenBackground]#NEW FEATURE# a|The `customCSS` property in the `customizations` object supports new variables to customize the UI elements on Liveboard, visualization, and Answer pages. You can also use these variables to define custom styles in the CSS file. + +|[tag greenBackground]#NEW# a|The `customCSS` property in the `customizations` object supports new variables to customize the UI elements on Liveboard, visualization, and Answer pages. You can also use these variables to define custom styles in the CSS file. + For more information, see xref:css-customization.adoc[Customize CSS]. -|[tag greenBackground]#NEW FEATURE# |The new version of the SDK allows fetching TML objects via `GetTML` host event. This event is triggered when a user clicks on the *Show underlying data* action on a Liveboard visualization or Answer page. + +|[tag greenBackground]#NEW# |The new version of the SDK allows fetching TML objects via `GetTML` host event. This event is triggered when a user clicks on the *Show underlying data* action on a Liveboard visualization or Answer page. + For more information, see xref:HostEvent.adoc#_gettml[GetTML]. -|[tag greenBackground]#NEW FEATURE# a| The new version of the SDK introduces the following enums in the `Action` object: +|[tag greenBackground]#NEW# a| The new version of the SDK introduces the following enums in the `Action` object: * `Action.SyncToOtherApps` + * `Action.SyncToSheets` + @@ -1441,9 +1570,9 @@ The new version of the SDK introduces several new features and enhancements. * `AuthType.OIDC` is renamed as `AuthType.OIDCRedirect` + * `AuthType.AuthServer` is renamed to `AuthType.TrustedAuthToken` + This enhancement does not introduce any breaking changes to your current implementation. -|[tag greenBackground]#NEW FEATURE# a|To use your current SAML or OIDC authentication setup and redirect users to the IdP for authentication within the embedded iFrame, you can now use `AuthType.EmbeddedSSO`. + +|[tag greenBackground]#NEW# a|To use your current SAML or OIDC authentication setup and redirect users to the IdP for authentication within the embedded iFrame, you can now use `AuthType.EmbeddedSSO`. + For more information, see xref:embed-authentication.adoc[Authentication]. -|[tag greenBackground]#NEW FEATURE#| +|[tag greenBackground]#NEW#| The `customizations` object in the SDK allows you to specify a custom CSS URL. You can also use this object to define CSS variables directly in the `init` code. + For more information, see xref:css-customization.adoc[Customize CSS]. |==== @@ -1455,7 +1584,7 @@ The new version of the SDK includes bug fixes and improvements to the new Livebo == Version 1.15.1, September 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#| +|[tag greenBackground]#NEW#| The `prefetch` method now supports the `url` and `prefetchFeatures` parameters. You can use these parameters to call the prefetch method before `init` and prefetch static resources on application load. + For more information, see xref:prefetch-and-cache.adoc[Prefetch static resources]. |==== @@ -1463,12 +1592,12 @@ For more information, see xref:prefetch-and-cache.adoc[Prefetch static resources == Version 1.15.0, September 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#| +|[tag greenBackground]#NEW#| For embedded instances with the new Liveboard experience, the Visual Embed SDK provides the `activeTabId` attribute, using which you can set a Liveboard tab as an active tab. For more information, see xref:embed-pinboard.adoc#_liveboard_tabs[Customize Liveboard tabs]. -|[tag greenBackground]#NEW FEATURE# a|The new version of the SDK supports firing events for Liveboard menu actions from the host application. The SDK introduces the following host event enumeration members for Liveboard objects: +|[tag greenBackground]#NEW# a|The new version of the SDK supports firing events for Liveboard menu actions from the host application. The SDK introduces the following host event enumeration members for Liveboard objects: * CopyLink * CreateMonitor @@ -1493,7 +1622,7 @@ For more information, see xref:events-hostEvents.adoc[Events reference]. == Version 1.14.0, August 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#| +|[tag greenBackground]#NEW#| The Visual Embed SDK now includes the `liveboardV2` attribute in the `LiveboardEmbed` package to allow developers to enable the new Liveboard experience on their embedded ThoughtSpot instance. + For more information, see xref:embed-pinboard.adoc[Embed a Liveboard]. |[tag orangeBackground]#MODIFIED#|If trusted authentication is enabled, the SDK makes a `POST` API call to get a login token and log the user into ThoughtSpot. @@ -1503,13 +1632,13 @@ The earlier versions of the SDK supported only `GET` API requests. For more info == Version 1.13.0, July 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#| +|[tag greenBackground]#NEW#| This version of Visual Embed SDK includes the `enableSearchAssist` attribute, using which you can turn on the Search Assist feature on an embedded instance. -|[tag greenBackground]#NEW FEATURE#| The new version of SDK introduces the `AuthType.SAML` enum for SAML-based SSO authentication. Note that `AuthType.SAML` replaces the `AuthType.SSO` enum, which is deprecated in the v1.13.0 version of the SDK. + +|[tag greenBackground]#NEW#| The new version of SDK introduces the `AuthType.SAML` enum for SAML-based SSO authentication. Note that `AuthType.SAML` replaces the `AuthType.SSO` enum, which is deprecated in the v1.13.0 version of the SDK. + For more information, see xref:embed-authentication.adoc#saml-sso-embed[Authentication]. |[tag redBackground]#DEPRECATED#| The `AuthType.SSO` enum is deprecated in v1.13.0. ThoughtSpot recommends using `AuthType.SAML` for the SAML SSO authentication method. + This change does not impact your current embed implementation with `AuthType.SSO`. -|[tag greenBackground]#NEW FEATURE#| The SDK includes the `getExportRequestForCurrentPinboard` event, which is triggered when a user tries to export a Liveboard in its current state. + +|[tag greenBackground]#NEW#| The SDK includes the `getExportRequestForCurrentPinboard` event, which is triggered when a user tries to export a Liveboard in its current state. + For more information, see xref:events-hostEvents.adoc[Events reference]. |==== @@ -1517,11 +1646,11 @@ For more information, see xref:events-hostEvents.adoc[Events reference]. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#| +|[tag greenBackground]#NEW#| This version of Visual Embed SDK introduces the `navigate` host event, which is triggered when a user navigates to an application page without a page reload. For more information, see xref:events-hostEvents.adoc[Events reference]. -|[tag greenBackground]#NEW FEATURE# | The new `getThoughtSpotPostUrlParams` method fetches ThoughtSpot URL query parameters prefixed with `ts-`. +|[tag greenBackground]#NEW# | The new `getThoughtSpotPostUrlParams` method fetches ThoughtSpot URL query parameters prefixed with `ts-`. |==== == Version 1.11.2, June 2022 @@ -1532,14 +1661,14 @@ Bug fix for Typescript builds that affect Angular project configurations. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#| The SDK includes the action enum `ReportError`, using which you can turn off ThoughtSpot-specific error reporting. +|[tag greenBackground]#NEW#| The SDK includes the action enum `ReportError`, using which you can turn off ThoughtSpot-specific error reporting. |==== == Version 1.11.0, May 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| The new version of SDK includes the following new events: +|[tag greenBackground]#NEW# a| The new version of SDK includes the following new events: * `ALL` * `AnswerChartSwitcher` @@ -1565,16 +1694,16 @@ Bug fix for Typescript builds that affect Angular project configurations. * `VizPointClick` For more information about how to register and handle these events, see xref:embed-events.adoc[Events and app integration]. -|[tag greenBackground]#NEW FEATURE# a| The new version of SDK supports the `showAlerts` attribute, using which you can show or hide alerts and error messages in the embedded view. +|[tag greenBackground]#NEW# a| The new version of SDK supports the `showAlerts` attribute, using which you can show or hide alerts and error messages in the embedded view. -|[tag greenBackground]#NEW FEATURE# a| The `Action.CreateMonitor` enumeration is available in the SDK for embedded ThoughtSpot environments on which the *Monitor* feature is enabled. +|[tag greenBackground]#NEW# a| The `Action.CreateMonitor` enumeration is available in the SDK for embedded ThoughtSpot environments on which the *Monitor* feature is enabled. For more information, see xref:embed-actions.adoc[Show or hide UI actions]. |==== == Version 1.10.4, May 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#|The `detectCookieAccessSlow` parameter in the SDK allows your app to check if third-party cookies are enabled on the browser. This parameter is available only for trusted and `Basic` authentication types. +|[tag greenBackground]#NEW#|The `detectCookieAccessSlow` parameter in the SDK allows your app to check if third-party cookies are enabled on the browser. This parameter is available only for trusted and `Basic` authentication types. |==== == Version 1.10.3, May 2022 @@ -1583,14 +1712,14 @@ Bug fix and improvements to the `logout` method. == Version 1.10.2, May 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#|Ability to configure `redirectPath` on the origin when using the SAMLRedirect `authType`. +|[tag greenBackground]#NEW#|Ability to configure `redirectPath` on the origin when using the SAMLRedirect `authType`. |==== == Version 1.10.1, May 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#|You can now use the `logout` method to log out embed users. +|[tag greenBackground]#NEW#|You can now use the `logout` method to log out embed users. |[tag orangeBackground]#MODIFIED# a| Note the following changes: + * You can now use the `loginFailedMessage` property on init to display the `Not logged in` message when a user login fails. You can customize this message by defining a custom text string in the `loginFailedMessage` attribute. @@ -1601,14 +1730,14 @@ Bug fix and improvements to the `logout` method. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| The `AddRemoveColumns` event is now available in the SDK. For more information, see xref:event-embedEvents.adoc[Events reference]. +|[tag greenBackground]#NEW# a| The `AddRemoveColumns` event is now available in the SDK. For more information, see xref:event-embedEvents.adoc[Events reference]. |==== == Version 1.9.8, April 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#|The `pageId` attribute now allows you to set the **SpotIQ** page as the home tab of your embedded ThoughtSpot app. +|[tag greenBackground]#NEW#|The `pageId` attribute now allows you to set the **SpotIQ** page as the home tab of your embedded ThoughtSpot app. For more information, see xref:full-embed.adoc[Embed full application]. |==== @@ -1620,7 +1749,7 @@ Bug fixes and improvements == Version 1.9.5, April 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#|The `locale` attribute is now available in embed packages. You can use this attribute to set the locale or language of your embedded application view. +|[tag greenBackground]#NEW#|The `locale` attribute is now available in embed packages. You can use this attribute to set the locale or language of your embedded application view. For more information, see xref:locale-setting.adoc[Set locale and display language]. |==== @@ -1632,7 +1761,7 @@ Bug fixes and improvements to React components. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#| The SDK now supports the `disableLoginRedirect` attribute to improve the login experience for your application users. When enabled, this attribute prevents your app from redirecting users to the login page when their session expires. + +|[tag greenBackground]#NEW#| The SDK now supports the `disableLoginRedirect` attribute to improve the login experience for your application users. When enabled, this attribute prevents your app from redirecting users to the login page when their session expires. + You can use this attribute along with `autoLogin` to automatically authenticate and re-login a user. + This feature is applicable to token-based authentication, that is, when the `AuthType` is set as `TrustedAuthToken` in the SDK. @@ -1642,7 +1771,7 @@ For more information, see xref:embed-authentication.adoc#trusted-auth-embed[Auth == Version 1.9.2, March 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#| You can now trigger events on React components using the `useEmbedRef` hook. +|[tag greenBackground]#NEW#| You can now trigger events on React components using the `useEmbedRef` hook. For more information, see xref:embed-ts-react-app.adoc[Embed ThoughtSpot in a React app]. |==== @@ -1650,11 +1779,11 @@ For more information, see xref:embed-ts-react-app.adoc[Embed ThoughtSpot in a Re == Version 1.9.1, March 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE#| The SDK now includes the `visibleVizs` attribute in the `LiveboardEmbed` package. This attribute allows you to add visualization GUIDs that you want to display when a Liveboard renders for the first time. +|[tag greenBackground]#NEW#| The SDK now includes the `visibleVizs` attribute in the `LiveboardEmbed` package. This attribute allows you to add visualization GUIDs that you want to display when a Liveboard renders for the first time. For more information, see xref:embed-pinboard.adoc[Embed a Liveboard]. -|[tag greenBackground]#NEW FEATURE# a| The following events are now available in the SDK: + +|[tag greenBackground]#NEW# a| The following events are now available in the SDK: + * `LiveboardRendered` (EmbedEvent) @@ -1664,7 +1793,7 @@ For more information, see xref:event-embedEvents.adoc[Events reference]. == Version 1.9.0, March 2022 [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a| The SDK now includes the following new enumerations for UI actions: +|[tag greenBackground]#NEW# a| The SDK now includes the following new enumerations for UI actions: * `Action.AnswerDelete` + * `Action.AnswerChartSwitcher` + @@ -1673,7 +1802,7 @@ For more information, see xref:event-embedEvents.adoc[Events reference]. For more information, see xref:embed-actions.adoc#standard-actions[Show or hide UI actions]. -|[tag greenBackground]#NEW FEATURE# a| The SDK now supports the `UpdateRuntimeFilters` host event. For more information, see xref:events-hostEvents.adoc[Events reference]. +|[tag greenBackground]#NEW# a| The SDK now supports the `UpdateRuntimeFilters` host event. For more information, see xref:events-hostEvents.adoc[Events reference]. |==== == Version 1.8.x, February 2022 @@ -1681,7 +1810,7 @@ For more information, see xref:embed-actions.adoc#standard-actions[Show or hide [width="100%" cols="1,4"] |==== |[tag redBackground]#BREAKING CHANGE# | The `autoLogin` attribute is now set as `false` by default. This attribute is used in the `init` method to automatically re-login a user when a session expires. -|[tag greenBackground]#NEW FEATURE# | The `init` method now returns the `authPromise` which resolves when a user authentication is completed. +|[tag greenBackground]#NEW# | The `init` method now returns the `authPromise` which resolves when a user authentication is completed. |==== @@ -1690,12 +1819,12 @@ For more information, see xref:embed-actions.adoc#standard-actions[Show or hide [width="100%" cols="1,4"] |==== | -[tag greenBackground]#NEW FEATURE# |+++
OIDC AuthType
+++ +[tag greenBackground]#NEW# |+++
OIDC AuthType
+++ The SDK supports the `OIDC` `authType` in `init` calls. If you want your application users to authenticate to an OpenID provider and use their SSO credentials to access the embedded ThoughtSpot content, you can enable the `OIDC` authentication type in the SDK. For more information, see xref:embed-authentication.adoc#oidc-auth[Authentication and security attributes]. -|[tag greenBackground]#NEW FEATURE# a|+++
Embed events
+++ +|[tag greenBackground]#NEW# a|+++
Embed events
+++ The SDK includes the following new event: @@ -1709,7 +1838,7 @@ For more information, see xref:event-embedEvents.adoc[Events reference]. [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a|+++
Visible actions
+++ +|[tag greenBackground]#NEW# a|+++
Visible actions
+++ You can now configure a set of ThoughtSpot UI actions as visible actions and display these actions in the embedded UI. If your embedded instance requires only a few actions, you can use the `visibleActions` API to show only these actions in the embedded ThoughtSpot UI. @@ -1719,7 +1848,7 @@ For more information, see xref:embed-actions.adoc[Show or hide UI actions]. The SDK library and object parameter names are modified to rebrand pinboards as Liveboards. For a complete list of changes, see xref:terminology-update.adoc#sdk-changes[Terminology changes]. -|[tag greenBackground]#NEW FEATURE# a|+++
Embed events
+++ +|[tag greenBackground]#NEW# a|+++
Embed events
+++ The SDK supports the following new events: @@ -1734,17 +1863,17 @@ For more information, see xref:event-embedEvents.adoc[Events reference]. [width="100%" cols="1,4"] |==== || -|[tag greenBackground]#NEW FEATURE# | +++
Render embedded objects in queue
+++ +|[tag greenBackground]#NEW# | +++
Render embedded objects in queue
+++ The SDK now supports rendering embedded objects in a queue. If you have multiple embedded objects, you can enable the `queueMultiRenders` parameter to queue your embedded objects and render them one after another. This feature helps in decreasing the load on the web browsers and improving your application loading experience. By default, this attribute is set to `false`. -|[tag greenBackground]#NEW FEATURE# a|+++
Liveboard embed
+++ +|[tag greenBackground]#NEW# a|+++
Liveboard embed
+++ The `pinboardEmbed` package includes the `defaultHeight` attribute that sets a minimum height for embedded objects on a pinboard page, and the corresponding visualization pages that a user can navigate to. For more information, see xref:embed-search.adoc[Embed a pinboard]. -|[tag greenBackground]#NEW FEATURE# a|+++
Embed events
+++ +|[tag greenBackground]#NEW# a|+++
Embed events
+++ The SDK EmbedEvent library includes the following new events: @@ -1761,19 +1890,19 @@ For more information, see xref:event-embedEvents.adoc[Events reference]. [width="100%" cols="1,4"] |==== || -|[tag greenBackground]#NEW FEATURE# a|+++
+++Prefetch API+++
+++ +|[tag greenBackground]#NEW# a|+++
+++Prefetch API+++
+++ The `prefetch` API fetches static resources from a given URL before your application loads. Web browsers can then cache the prefetched resources locally and serve them from a user's local disk. You can use this API to load the embedded objects faster and improve your application response time. For more information, see xref:prefetch-and-cache.adoc[Prefetch static resources]. -|[tag greenBackground]#NEW FEATURE# a|+++
+++In-app page navigation+++
+++ +|[tag greenBackground]#NEW# a|+++
+++In-app page navigation+++
+++ The `navigateToPage` method in the SDK lets you provide quick and direct access to a specific pinboard, saved Answer, or an application page. You can add a custom menu action or button in your application UI that calls the `navigateToPage` method and leads your users to the page specified in the `path` parameter. For more information, see xref:page-navigation.adoc[Add a custom action for in-app navigation]. -|[tag greenBackground]#NEW FEATURE# a|+++
+++Full application embedding+++
+++ +|[tag greenBackground]#NEW# a|+++
+++Full application embedding+++
+++ The `appEmbed` SDK package includes the following new attributes: @@ -1783,7 +1912,7 @@ The `appEmbed` SDK package includes the following new attributes: For more information, see xref:full-embed.adoc[Embed full application]. -|[tag greenBackground]#NEW FEATURE# |+++
+++Search embed +++
+++ +|[tag greenBackground]#NEW# |+++
+++Search embed +++
+++ The `searchEmbed` package includes the `forceTable` attribute that sets tabular view as the default format for presenting search data. You can set this attribute to `true` to force search results to appear in the table view. @@ -1792,7 +1921,7 @@ For more information, see xref:embed-search.adoc[Embed ThoughtSpot search]. |[tag redBackground]#REMOVED# | The `searchQuery` parameter is no longer supported and is removed from the `searchEmbed` SDK package. -|[tag greenBackground]#NEW FEATURE# a|+++
+++Embed events +++
+++ +|[tag greenBackground]#NEW# a|+++
+++Embed events +++
+++ The SDK EmbedEvent library includes the following events: * `QueryChanged` @@ -1806,7 +1935,7 @@ For more information, see xref:embed-events.adoc[Events and app integration]. [width="100%" cols="1,4"] |==== || -|[tag greenBackground]#NEW FEATURE# a| +++
searchOptions
+++ +|[tag greenBackground]#NEW# a| +++
searchOptions
+++ The `searchEmbed` SDK package introduces the `searchOptions` parameter for setting search tokens. The `searchOptions` parameter includes the following attributes: @@ -1826,13 +1955,13 @@ The `searchQuery` parameter in the `searchEmbed` SDK package is deprecated in th For more information about `searchOptions`, see xref:embed-search.adoc#search-query[Embed ThoughtSpot search]. -|[tag greenBackground]#NEW FEATURE# a| +++
autoLogin
+++ +|[tag greenBackground]#NEW# a| +++
autoLogin
+++ The SDK now supports logging in users automatically after a user session has expired. For more information, see xref:embed-authentication.adoc#embed-session-sec[Embed user authentication]. -|[tag greenBackground]#NEW FEATURE# a| +++
shouldEncodeUrlQueryParams
+++ +|[tag greenBackground]#NEW# a| +++
shouldEncodeUrlQueryParams
+++ You can now convert query parameters in the ThoughtSpot generated URLs to base64-encoded format. You can enable this attribute to secure your cluster from cross-site scripting attacks. |[tag redBackground]#BREAKING CHANGE# a| +++
Data structure changes in custom action response payloads
+++ @@ -1851,16 +1980,16 @@ Includes user information such as username, GUID of the user, and email address. To view a sample response payload, see xref:callback-response-payload.adoc#search-data-payload[Custom action response payload]. -|[tag greenBackground]#NEW FEATURE# a| +++
preventPinboardFilterRemoval
+++ +|[tag greenBackground]#NEW# a| +++
preventPinboardFilterRemoval
+++ The `pinboardEmbed` SDK package now includes the `preventPinboardFilterRemoval` attribute. You can use this attribute to disable the filter removal action and thus prevent users from removing the filter chips added on a pinboard page. For more information, see xref:embed-pinboard.adoc[Embed a pinboard] and xref:embed-a-viz.adoc[Embed a visualization]. -|[tag greenBackground]#NEW FEATURE# a| +++
suppressNoCookieAccessAlert
+++ +|[tag greenBackground]#NEW# a| +++
suppressNoCookieAccessAlert
+++ You can now set custom alerts for `noCookieAccess` events. By default, the SDK triggers a `noCookieAccess` event and generates an alert when a user's browser blocks third-party cookies. The `suppressNoCookieAccessAlert` allows you to disable this alert. -|[tag greenBackground]#NEW FEATURE# a| +++
Support for fetching callback custom action payload in batches
+++ +|[tag greenBackground]#NEW# a| +++
Support for fetching callback custom action payload in batches
+++ The Visual Embed SDK now supports processing data in batches for callback custom action responses. The callback custom action event in the SDK package supports defining `batchSize` and `offset` values to paginate the Answer payload and send the records in batches. @@ -1872,13 +2001,13 @@ For more information, see xref:push-data-to-external-app.adoc#large-dataset[Call [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a|+++
SAML authentication
+++ +|[tag greenBackground]#NEW# a|+++
SAML authentication
+++ The Visual Embed SDK packages now include the `noRedirect` attribute as an optional parameter for the SAMLRedirect SSO `AuthType`. If you want to display the SAML authentication workflow in a pop-up window, instead of refreshing the application web page to direct users to the SAML login page, you can set the `noRedirect` attribute to `true`. For more information, see the instructions for embedding xref:full-embed.adoc[ThoughtSpot pages], xref:embed-search.adoc[search], xref:embed-pinboard.adoc[pinboard], and xref:embed-a-viz.adoc[visualizations]. -|[tag greenBackground]#NEW FEATURE# a|+++
Pinboard actions
+++ +|[tag greenBackground]#NEW# a|+++
Pinboard actions
+++ The *More* menu image:./images/icon-more-10px.png[the more options menu] in the embedded Pinboard page now shows the following actions for pinboard and visualizations. Pinboard:: @@ -1894,7 +2023,7 @@ Pinboard:: [NOTE] Users with edit permissions can view and access the *Save*, *Add filters*, *Configure filters*, and *Manage schedules* actions. -|[tag greenBackground]#NEW FEATURE# a|+++
Visualization actions
+++ +|[tag greenBackground]#NEW# a|+++
Visualization actions
+++ Visualizations on a pinboard: @@ -1915,7 +2044,7 @@ Users with edit permissions can view and access the *Edit* action. The *Download [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a|+++
NoCookieAccess event
+++ +|[tag greenBackground]#NEW# a|+++
NoCookieAccess event
+++ When a user accesses the embedded application from a web browser that has third-party cookies disabled, the Visual Embed SDK emits the `NoCookieAccess` event to notify the developer. Cookies are disabled by default in Safari. Users can enable third-party cookies in Safari’s Preferences setting page or use another web browser. To know how to enable this setting by default on Safari for a ThoughtSpot embedded instance, contact ThoughtSpot Support. diff --git a/modules/ROOT/pages/api-response-pagination.adoc b/modules/ROOT/pages/api-response-pagination.adoc index 855a505fc..73fb69d86 100644 --- a/modules/ROOT/pages/api-response-pagination.adoc +++ b/modules/ROOT/pages/api-response-pagination.adoc @@ -1,7 +1,7 @@ = Paginate API response :page-title: REST API response pagination -:page-pageid: rest-api-pagination +:page-pageid: rest-api-pagination-v1 :page-description: REST API response pagination When you make REST API calls to some endpoints to query visualization data, for instance `/tspublic/v1/pinboarddata`, the APIs may return many rows of data in response. You can paginate the JSON response and retain the order of data across all pages. Given the ability to paginate, you can quickly populate tables and make new REST calls every time you go to the next page of the data on the table. There is significant load time if you want to populate the data table with many rows (greater than 1000). diff --git a/modules/ROOT/pages/ask-docs.adoc b/modules/ROOT/pages/ask-docs.adoc deleted file mode 100644 index 2f9afba82..000000000 --- a/modules/ROOT/pages/ask-docs.adoc +++ /dev/null @@ -1,9 +0,0 @@ -= Ask Docs -:toc: true - -:page-title: Ask Visual Embed SDK Docs -:page-pageid: ask-docs -:page-description: ThoughtSpot Embed SDK docs GPT Q&A - -This is ThoughtSpot SDK Q&A. - diff --git a/modules/ROOT/pages/catalog-and-audit.adoc b/modules/ROOT/pages/catalog-and-audit.adoc index a945884b4..ebaab6156 100644 --- a/modules/ROOT/pages/catalog-and-audit.adoc +++ b/modules/ROOT/pages/catalog-and-audit.adoc @@ -24,7 +24,7 @@ The `/metadata/listobjectheaders` API is paginated by default. You can return th The REST API provides a xref:metadata-api.adoc#metadata-details[metadata/details] endpoint that returns very complex objects with all the metadata available. For purposes of cataloging, it may be easier to use a combination of the metadata list methods and the TML APIs to build a picture of what is available. -For example, to know the columns and data types of a table, you can get the table's GUID from the `metadata/listobjectheaders` endpoint, then request the TML for the table using the xref:tml-api.adoc[TML APIs]. If you need more complex data of how ThoughtSpot stores the columns internally, then use the `metadata/details` endpoint. +For example, to know the columns and data types of a table, you can get the table's GUID from the `metadata/listobjectheaders` endpoint, then request the TML for the table using the xref:tml-export.adoc[TML export API]. If you need more complex data of how ThoughtSpot stores the columns internally, then use the `metadata/details` endpoint. == Retrieve object access (sharing) diff --git a/modules/ROOT/pages/collections.adoc b/modules/ROOT/pages/collections.adoc index 53dfbd7a6..62cabb52c 100644 --- a/modules/ROOT/pages/collections.adoc +++ b/modules/ROOT/pages/collections.adoc @@ -9,6 +9,11 @@ ThoughtSpot now provides REST APIs that enable developers to organize different ThoughtSpot objects into an organizational container called *Collections*. These objects can be Liveboards, Answers, data models, tables, and even other Collections. Collections provide a powerful way to manage your data assets, making discovery and collaboration easier, while ensuring the integrity of embedded workflows. +You can also embed the Collections page directly in your application using the Visual Embed SDK. +To navigate users to the Collections page in full application embedding, set `pageId` to `Page.Collections` in `AppViewConfig`. +For more information, see xref:customize-nav-full-embed.adoc#_navigate_to_the_collections_page[Navigate to the Collections page]. + + == Before you begin * For REST API v2 operations, the Org context is determined based on the authentication token used in your API requests. Ensure you log in to the appropriate Org context from which you want to send API requests. diff --git a/modules/ROOT/pages/common/nav-embedding.adoc b/modules/ROOT/pages/common/nav-embedding.adoc index c65bdd872..dbcec8c9d 100644 --- a/modules/ROOT/pages/common/nav-embedding.adoc +++ b/modules/ROOT/pages/common/nav-embedding.adoc @@ -7,26 +7,31 @@ [.sidebar-title] Embed ThoughtSpot in a web app -* link:{{navprefix}}/getting-started[Embed with Visual Embed SDK] -* link:{{navprefix}}/tsembed[Quickstart guide] -* link:{{navprefix}}/embed-ai-search-analytics[Embed AI Search and Analytics] -** link:{{navprefix}}/embed-spotter[Embed Spotter experience] -*** link:{{navprefix}}/customize-spotter-embed[Customize Spotter interface] -** link:{{navprefix}}/embed-spotter-agent[Embed Spotter Agent] -* link:{{navprefix}}/embed-liveboard[Embed Analytics] +* link:{{navprefix}}/tsembed[Embed with Visual Embed SDK] +* link:{{navprefix}}/getting-started[Get started] +* link:{{navprefix}}/embed-ai-search-analytics[Embed Spotter AI Analytics] +** link:{{navprefix}}/embed-spotter[Embed full Spotter experience] +** link:{{navprefix}}/customize-spotter-embed[Customize Spotter interface] +** link:{{navprefix}}/customize-spotter-chat-experience[Customize chat experience] +** link:{{navprefix}}/customize-spotter-sidebar[Customize sidebar panel] +** link:{{navprefix}}/customize-spotter-sharing[Customize conversation sharing experience] +** link:{{navprefix}}/customize-spotter-analysts[Configure Spotter Analysts] +** link:{{navprefix}}/embed-spotter-agent[Embed Spotter without ThoughtSpot UI] +* Embed charts and Liveboards ** link:{{navprefix}}/embed-liveboard[Embed a Liveboard] ** link:{{navprefix}}/spotterViz-agent[SpotterViz AI agent in Liveboards] ** link:{{navprefix}}/embed-a-viz[Embed a visualization] * link:{{navprefix}}/full-embed[Embed full application] ** link:{{navprefix}}/full-app-customize[Customize your embed] ** link:{{navprefix}}/customize-nav-controls[Customize navigation panels] -** link:{{navprefix}}/set-default-page[Customize default page and navigation path] +** link:{{navprefix}}/set-default-page[Set default landing page and navigation] ** link:{{navprefix}}/customize-homepage-experience[Customize home page experience] * Embed token-based Search -** link:{{navprefix}}/search-embed[Embed Search] -** link:{{navprefix}}/embed-searchbar[Embed search bar] +** link:{{navprefix}}/search-embed[Embed Search page] +** link:{{navprefix}}/embed-searchbar[Embed Search bar] ** link:{{navprefix}}/visualization-overrides[Visualization overrides] * link:{{navprefix}}/react-app-embed[Embed with React components] +* +++Visual Embed Playground+++ [.sidebar-title] Embed ThoughtSpot in a mobile app @@ -110,7 +115,6 @@ Customize and integrate * link:{{navprefix}}/set-locale[Customize locale] * link:{{navprefix}}/custom-domain-config[Custom domain configuration] * link:{{navprefix}}/customize-emails[Customize onboarding settings] -* link:{{navprefix}}/customize-email-apis[Customize email template] * link:{{navprefix}}/in-app-navigation[Create dynamic menus and navigation] * link:{{navprefix}}/best-practices[Performance optimization] ** link:{{navprefix}}/best-practices[Best practices] @@ -120,10 +124,7 @@ Customize and integrate * link:{{navprefix}}/troubleshoot-errors[Troubleshoot errors] -[.sidebar-title] -Embedding tutorials -* link:{{navprefix}}/tutorials/tutorials-overview[Embedding tutorials] //// * link:{{navprefix}}/tutorials/tse-fundamentals/intro[Embedding Fundamentals] @@ -158,7 +159,6 @@ Embedding tutorials [.sidebar-title] Reference guides and changelog -* +++Visual Embed Playground+++ * link:{{navprefix}}/VisualEmbedSdk[Visual Embed SDK Reference] include::generated/typedoc/CustomSideNav.adoc[] ** Custom styles @@ -181,6 +181,11 @@ include::generated/typedoc/CustomSideNav.adoc[] ** link:{{navprefix}}/embed-sdk-changelog[Visual Embed SDK] ** link:{{navprefix}}/mobile-sdk-changelog[Mobile Embed SDK] +[.sidebar-title] +Embedding tutorials + +* link:{{navprefix}}/tutorials/tutorials-overview[Embedding tutorials] + [.sidebar-title] Additional resources diff --git a/modules/ROOT/pages/common/nav-in-product-help.adoc b/modules/ROOT/pages/common/nav-in-product-help.adoc index c35a26af7..5baf2043f 100644 --- a/modules/ROOT/pages/common/nav-in-product-help.adoc +++ b/modules/ROOT/pages/common/nav-in-product-help.adoc @@ -20,7 +20,6 @@ Live Playgrounds * +++Visual Embed Playground+++ ** link:{{navprefix}}/dev-playground[How to use] * link:{{navprefix}}/restV2-playground?apiResourceId=http%2Fgetting-started%2Fintroduction[REST API v2 Playground] -** link:{{navprefix}}/rest-playground[How to use] * +++Theme Builder+++ ** link:{{navprefix}}/theme-builder-doc[How to use] @@ -29,17 +28,22 @@ Embed ThoughtSpot in a web app * link:{{navprefix}}/getting-started[Embed with Visual Embed SDK] * link:{{navprefix}}/tsembed[Quickstart guide] -* link:{{navprefix}}/embed-ai-search-analytics[Embed AI Search and Analytics] -** link:{{navprefix}}/embed-spotter[Embed Spotter experience] -** link:{{navprefix}}/embed-spotter-agent[Embed Spotter Agent] -* link:{{navprefix}}/embed-liveboard[Embed Analytics] +* link:{{navprefix}}/embed-ai-search-analytics[Embed Spotter AI Analytics] +** link:{{navprefix}}/embed-spotter[Embed full Spotter experience] +** link:{{navprefix}}/customize-spotter-embed[Customize Spotter interface] +** link:{{navprefix}}/customize-spotter-chat-experience[Customize chat experience] +** link:{{navprefix}}/customize-spotter-sidebar[Customize sidebar panel] +** link:{{navprefix}}/customize-spotter-sharing[Customize conversation sharing experience] +** link:{{navprefix}}/customize-spotter-analysts[Configure Spotter Analysts] +** link:{{navprefix}}/embed-spotter-agent[Embed Spotter AI without ThoughtSpot UI] +* link:{{navprefix}}/embed-liveboard[Embed live analytics] ** link:{{navprefix}}/embed-liveboard[Embed a Liveboard] ** link:{{navprefix}}/spotterViz-agent[SpotterViz AI agent in Liveboards] ** link:{{navprefix}}/embed-a-viz[Embed a visualization] * link:{{navprefix}}/full-embed[Embed full application] ** link:{{navprefix}}/full-app-customize[Customize your embed] ** link:{{navprefix}}/customize-nav-controls[Customize navigation panels] -** link:{{navprefix}}/set-default-page[Customize default page and navigation path] +** link:{{navprefix}}/set-default-page[Set default landing page and navigation] ** link:{{navprefix}}/customize-homepage-experience[Customize home page experience] * Embed token-based Search ** link:{{navprefix}}/search-embed[Embed Search] @@ -221,9 +225,15 @@ REST APIs *** link:{{navprefix}}/rest-apiv2-users-search[Search users] *** link:{{navprefix}}/rest-apiv2-groups-search[Search groups] *** link:{{navprefix}}/rest-apiv2-metadata-search[Search metadata] -** link:{{navprefix}}/fetch-data-and-report-apis[Data and Report APIs] +** link:{{navprefix}}/fetch-data-and-report-apis[Data APIs] +** link:{{navprefix}}/report-apis[Report APIs] ** link:{{navprefix}}/spotter-api[Spotter APIs] *** link:{{navprefix}}/spotter-agent-apis[AI APIs (Spotter Agent and Spotter 3)] +*** link:{{navprefix}}/spotter-agent-conversation-apis[Spotter agent conversation APIs] +*** link:{{navprefix}}/spotter-agent-streaming-apis[Spotter agent streaming APIs] +*** link:{{navprefix}}/process-conversation-output[Process Spotter agent conversation results] +*** link:{{navprefix}}/spotter-agent-data-literacy-apis[Spotter agent data literacy APIs] +*** link:{{navprefix}}/spotter-agent-sharing-apis[Spotter agent conversation sharing APIs] *** link:{{navprefix}}/spotter-agent-instructions[Spotter AI agent instructions] *** link:{{navprefix}}/spotter-agent-conversation-mgmt-apis[APIs for managing saved conversations] *** link:{{navprefix}}/spotter-memory-migration[Spotter memory migration API] @@ -232,6 +242,8 @@ REST APIs ** link:{{navprefix}}/style-customization-apis[Style customization APIs] ** link:{{navprefix}}/audit-logs[Audit logs] ** link:{{navprefix}}/tml[TML] +*** link:{{navprefix}}/tml-import[Import TML] +*** link:{{navprefix}}/tml-export[Export TML] ** link:{{navprefix}}/collections[Collections] ** link:{{navprefix}}/connections[Connections] ** link:{{navprefix}}/connection-config[Connection configuration] @@ -242,7 +254,7 @@ REST APIs [.sidebar-title] REST API SDK -* link:{{navprefix}}/rest-api-sdk[Overview] +* link:{{navprefix}}/rest-api-sdk-libraries[Overview] * link:{{navprefix}}/rest-api-sdk-typescript[TypeScript SDK] * link:{{navprefix}}/rest-api-sdk-java[Java SDK] * link:{{navprefix}}/python-sdk[Python SDK] diff --git a/modules/ROOT/pages/common/nav-release-notes.adoc b/modules/ROOT/pages/common/nav-release-notes.adoc index 061b9ec4d..75c6a169b 100644 --- a/modules/ROOT/pages/common/nav-release-notes.adoc +++ b/modules/ROOT/pages/common/nav-release-notes.adoc @@ -5,13 +5,12 @@ [navSection] [.sidebar-title] -Release notes and changelogs +Release notes * link:{{navprefix}}/whats-new[What's new] -* Changelog -** link:{{navprefix}}/embed-sdk-changelog[Visual Embed SDK changelog] -** link:{{navprefix}}/mobile-sdk-changelog[Mobile Embed SDK changelog] -** link:{{navprefix}}/rest-v2-changelog[REST API v2 changelog] -** link:{{navprefix}}/mcp-server-changelog[Spotter MCP Server changelog] +* link:{{navprefix}}/embed-sdk-changelog[Visual Embed SDK changelog] +* link:{{navprefix}}/mobile-sdk-changelog[Mobile Embed SDK changelog] +* link:{{navprefix}}/rest-v2-changelog[REST API v2 changelog] +* link:{{navprefix}}/mcp-server-changelog[Spotter MCP Server changelog] * link:{{navprefix}}/deprecated-features[Deprecation announcements] diff --git a/modules/ROOT/pages/common/nav-rest-api.adoc b/modules/ROOT/pages/common/nav-rest-api.adoc index 4fb2e1807..0251c0f31 100644 --- a/modules/ROOT/pages/common/nav-rest-api.adoc +++ b/modules/ROOT/pages/common/nav-rest-api.adoc @@ -5,38 +5,75 @@ [navSection] [.sidebar-title] -REST APIs +ThoughtSpot REST APIs * link:{{navprefix}}/rest-apis[Overview] * link:{{navprefix}}/rest-apiv2-getstarted[Get started] -* link:{{navprefix}}/api-authv2[REST API v2.0 authentication] * link:{{navprefix}}/rest-v2-changelog[REST API v2 changelog] * link:{{navprefix}}/restV2-playground?apiResourceId=http%2Fgetting-started%2Fintroduction[REST API v2 Playground] + +[.sidebar-title] +REST API endpoints + * link:{{navprefix}}/rest-apiv2-reference[REST API v2.0 Reference] +* Authentication and administration +** link:{{navprefix}}/api-authv2[REST API v2.0 authentication] ** link:{{navprefix}}/api-user-management[Users and group privileges] ** link:{{navprefix}}/rbac[Role-based access control] -** link:{{navprefix}}/rest-apiv2-search[Search API endpoints] -*** link:{{navprefix}}/rest-apiv2-users-search[Search users] -*** link:{{navprefix}}/rest-apiv2-groups-search[Search groups] -*** link:{{navprefix}}/rest-apiv2-metadata-search[Search metadata] -** link:{{navprefix}}/fetch-data-and-report-apis[Data and Report APIs] -** link:{{navprefix}}/runtime-sort[Runtime sorting] -** link:{{navprefix}}/spotter-api[Spotter APIs] -*** link:{{navprefix}}/spotter-agent-apis[AI APIs (Spotter Agent and Spotter 3)] -*** link:{{navprefix}}/spotter-agent-instructions[Spotter AI agent instructions] -*** link:{{navprefix}}/spotter-agent-conversation-mgmt-apis[APIs for managing saved conversations] -*** link:{{navprefix}}/spotter-memory-migration[Spotter memory migration API] -*** link:{{navprefix}}/spotter-apis-classic[AI APIs (Spotter Classic) ^BETA^] -*** link:{{navprefix}}/spotter-nl-instructions[Data model instructions APIs ^BETA^] ** link:{{navprefix}}/audit-logs[Audit logs] -** link:{{navprefix}}/tml[TML] -** link:{{navprefix}}/collections[Collections] + +* Multi-tenancy and Orgs +** link:{{navprefix}}/orgs-api-op[Orgs APIs] +** link:{{navprefix}}/variables[Variable APIs] +** link:{{navprefix}}/timezone-aware-filtering[Timezone-aware keywords and filters] +** link:{{navprefix}}/parameterize-metadata[Metadata parameterization APIs] +** link:{{navprefix}}/publish-to-orgs[Publish objects to Orgs] + +* link:{{navprefix}}/spotter-api[Spotter APIs] +** link:{{navprefix}}/spotter-agent-apis[Spotter AI agent APIs (Spotter Agent and Spotter 3)] +** link:{{navprefix}}/spotter-agent-conversation-apis[Spotter agent conversation APIs] +** link:{{navprefix}}/spotter-agent-streaming-apis[Spotter agent streaming APIs] +** link:{{navprefix}}/spotter-agent-data-literacy-apis[Spotter agent data literacy APIs] +** link:{{navprefix}}/spotter-agent-sharing-apis[Spotter agent conversation sharing APIs] +** link:{{navprefix}}/spotter-agent-instructions[Spotter AI agent instructions] +** link:{{navprefix}}/spotter-agent-conversation-mgmt-apis[APIs for managing saved conversations] +** link:{{navprefix}}/spotter-memory-migration[Spotter memory migration API] +** link:{{navprefix}}/spotter-apis-classic[AI APIs (Spotter Classic)] +** link:{{navprefix}}/spotter-nl-instructions[Data model instructions APIs] +** link:{{navprefix}}/process-conversation-output[Export answers generated from a Spotter conversation] + +* Data and report APIs +** link:{{navprefix}}/fetch-data-and-report-apis[Data APIs] +** link:{{navprefix}}/report-apis[Report APIs] +** link:{{navprefix}}/runtime-sort[Runtime sorting] + +* link:{{navprefix}}/rest-apiv2-search[Search API endpoints] +** link:{{navprefix}}/rest-apiv2-users-search[Search users] +** link:{{navprefix}}/rest-apiv2-groups-search[Search groups] +** link:{{navprefix}}/rest-apiv2-metadata-search[Search metadata] + +* Data management APIs ** link:{{navprefix}}/connections[Connections] ** link:{{navprefix}}/connection-config[Connection configuration] ** link:{{navprefix}}/manual-translation-api[Manual translations] + +* TML APIs +** link:{{navprefix}}/tml[TML] +*** link:{{navprefix}}/tml-import[Import TML] +*** link:{{navprefix}}/tml-export[Export TML] + + +* Style and email customization APIs ** link:{{navprefix}}/style-customization-apis[Style customization APIs] -** link:{{navprefix}}/webhooks-rest-api[Webhook APIs] +** link:{{navprefix}}/customize-email-apis[Customize email template] + +* link:{{navprefix}}/collections[Collections] +* link:{{navprefix}}/webhooks-rest-api[Webhook APIs] +* Version control and Git integration +** link:{{navprefix}}/git-integration[Deploy with GitHub APIs (legacy)] +** link:{{navprefix}}/git-configuration[Configure GitHub integration] +** link:{{navprefix}}/git-api[GitHub REST APIs] [.sidebar-title] REST API SDK @@ -55,22 +92,15 @@ REST API tutorial * link:{{navprefix}}/tutorials/rest-api/intro[REST API tutorial] -//// -* link:{{navprefix}}/tutorials/rest-api/lesson-01[01 - REST API overview] -* link:{{navprefix}}/tutorials/rest-api/lesson-02[02 - Simple Python implementation] -* link:{{navprefix}}/tutorials/rest-api/lesson-03[03 - Complex REST API workflows] - -//// - [.sidebar-title] REST API v1 (DEPRECATED) * link:{{navprefix}}/rest-api-getstarted[Get started] -* link:{{navprefix}}/api-auth-session[REST API v1 authentication] -* link:{{navprefix}}/catalog-and-audit[Catalog and audit content] -* link:{{navprefix}}/rest-api-pagination[Paginate API response] +** link:{{navprefix}}/api-auth-session[REST API v1 authentication] +** link:{{navprefix}}/catalog-and-audit[Catalog and audit content] +** link:{{navprefix}}/rest-api-pagination-v1[Paginate API response] * link:{{navprefix}}/rest-api-reference[REST API v1 Reference] -* link:{{navprefix}}/rest-v1-changelog[REST API v1 changelog] +//* link:{{navprefix}}/rest-v1-changelog[REST API v1 changelog] * link:{{navprefix}}/v1v2-comparison[REST v1 and v2.0 comparison] [.sidebar-title] diff --git a/modules/ROOT/pages/common/nav.adoc b/modules/ROOT/pages/common/nav.adoc index ef2504da5..ca8e68e82 100644 --- a/modules/ROOT/pages/common/nav.adoc +++ b/modules/ROOT/pages/common/nav.adoc @@ -25,7 +25,6 @@ Live Playgrounds ** link:{{navprefix}}/dev-playground[How to use] * link:{{navprefix}}/restV2-playground?apiResourceId=http%2Fgetting-started%2Fintroduction[REST API v2 Playground] -** link:{{navprefix}}/rest-playground[How to use] //** +++REST API v1 Playground+++ * +++Theme Builder+++ ** link:{{navprefix}}/theme-builder-doc[How to use] @@ -57,23 +56,19 @@ Integration Guides [.sidebar-title] Deployment guides -* link:{{navprefix}}/thoughtspot-objects[ThoughtSpot objects] +* link:{{navprefix}}/thoughtspot-objects[ThoughtSpot objects overview] * link:{{navprefix}}/timezone-aware-filtering[Timezone-aware keywords and filters] -* link:{{navprefix}}/variables[Variables] -* link:{{navprefix}}/parameterize-metadata[Parameterize metadata] -* link:{{navprefix}}/development-and-deployment[Development and deployment] -* link:{{navprefix}}/deploy-with-tml-apis[Deploy with TML APIs] -** link:{{navprefix}}/git-provider-integration[Git provider integration] -** link:{{navprefix}}/modify-tml[TML modification] * link:{{navprefix}}/publish-data-overview[Publish content to Orgs] -** link:{{navprefix}}/publish-to-orgs[Publish objects to Orgs] -* link:{{navprefix}}/git-integration[Deploy with GitHub APIs (legacy)] -** link:{{navprefix}}/git-configuration[Configure GitHub integration] -** link:{{navprefix}}/git-api[GitHub REST APIs] -** link:{{navprefix}}/guid-mapping[GUID mapping] -* link:{{navprefix}}/multi-tenancy[Overview] +* link:{{navprefix}}/development-and-deployment[Development and deployment] +** link:{{navprefix}}/deploy-with-tml-apis[Deploy with TML APIs] +*** link:{{navprefix}}/git-provider-integration[Git provider integration] +*** link:{{navprefix}}/modify-tml[TML modification] +** link:{{navprefix}}/git-integration[Deploy with GitHub APIs (legacy)] +*** link:{{navprefix}}/git-configuration[Configure GitHub integration] +*** link:{{navprefix}}/git-api[GitHub REST APIs] +*** link:{{navprefix}}/guid-mapping[GUID mapping] +* link:{{navprefix}}/multi-tenancy[Multi-tenancy] ** link:{{navprefix}}/orgs[Multi-tenancy with Orgs] -** link:{{navprefix}}/orgs-api-op[Org administration] ** link:{{navprefix}}/multitenancy-within-an-org[Multi-tenancy within an Org] ** link:{{navprefix}}/single-tenant-data-models[Single-tenant data models with Orgs] * link:{{navprefix}}/tse-cluster[Cluster maintenance and upgrade] diff --git a/modules/ROOT/pages/connection-config.adoc b/modules/ROOT/pages/connection-config.adoc index 3dfcc186b..c39852647 100644 --- a/modules/ROOT/pages/connection-config.adoc +++ b/modules/ROOT/pages/connection-config.adoc @@ -51,6 +51,7 @@ In your `POST` request body, include the following parameters: * `SAGE_INDEXING` * `ROW_COUNT_STATS` +* `SCHEDULED_LIVEBOARDS` |===== diff --git a/modules/ROOT/pages/connections-api.adoc b/modules/ROOT/pages/connections-api.adoc index 8424f18e2..ba2877fd9 100644 --- a/modules/ROOT/pages/connections-api.adoc +++ b/modules/ROOT/pages/connections-api.adoc @@ -1,11 +1,12 @@ -= Data connection APIs += REST API v1 - Connection API endpoints :toc: true :toclevels: 1 :page-title: Data connection APIs -:page-pageid: connections-api +:page-pageid: connections-api-v1 :page-description: The connection API endpoints allow you to query data connections used for live query services on a ThoughtSpot instance +include::{path}/rest-apiv1-deprecation-note.adoc[] //// ThoughtSpot supports connecting to external data warehouses and using these as data sources for analytics and visualizations. ThoughtSpot users can run a live query of the data directly from the following external data sources to generate the information they need: diff --git a/modules/ROOT/pages/customize-links.adoc b/modules/ROOT/pages/customize-links.adoc index 310b00311..7c92d9edb 100644 --- a/modules/ROOT/pages/customize-links.adoc +++ b/modules/ROOT/pages/customize-links.adoc @@ -23,16 +23,16 @@ An Answer link is generated when a user shares an Answer with another user and i SpotIQ analyses links:: ThoughtSpot generates this link when a user runs the SpotIQ analysis on the data generated from a search query, saved Answer, or a visualization pinned to a Liveboard. This link points users to the *SpotIQ Analyses* page and is also sent in email notifications. - Links to unsubscribe from notifications:: -+ The *Unsubscribe* link is included in system-generated emails to allow users to turn off email notifications. * The *Unsubscribe* link is included in object share and Liveboard notifications. By default, the *Unsubscribe* link in these notifications points users to the *Profile* settings page in ThoughtSpot, using which they can turn off or enable email notifications. * If a user has subscribed to receive alerts for KPI charts, the email notifications include the *Unsubscribe* link. A user can click this link to unsubscribe from monitor alerts at any time. +Spotter conversation sharing link:: +The conversation sharing link is generated when a user shares a Spotter conversation from an embedded interface. Recipients use this link to open the shared conversation in the host application. + Generic link:: -+ The *Generic* link allows you to customize navigation links in your application that are not parameterized. For example, the top navigation menu links in your embedded application can be customized as *Generic link*. == Create dynamic routes for ThoughtSpot pages in embedding app @@ -65,7 +65,7 @@ xref:embed-search.adoc[SearchEmbed] component to an existing Answer: `{web-app-name}.{your-domain}.com/analytics/report/*{answerId}*` -== Link format for an embedded instance +== Link format for embedded views By default, ThoughtSpot generates these links with URL paths from the ThoughtSpot application context. If you have embedded ThoughtSpot in your application, you might want to generate links with the URL and resource paths from your host application context. For example, if your host app URL is `\https://www.mysite.com`, you may want to generate a Liveboard link with your host application URL instead of the standard ThoughtSpot portal URL. You can customize the format of system-generated links in the *Link settings* page of the *Develop* tab. @@ -198,6 +198,22 @@ https://www.mysite.com/?unsubscribe ---- + +[#conversation-share-link] +Spotter conversation sharing URL:: +If your deployment embeds Spotter, you can customize the conversation share link so that recipients open the shared conversation in your application instead of the ThoughtSpot standalone application. ++ +The conversation share link format string must include both of the following placeholders: + +* `{conversation-id}`: Replaced with the ID of the shared conversation when the link is generated. +* `{ts-query-params}`: Replaced with the query parameters that ThoughtSpot appends to the link. + ++ +The placeholders must be specified in the `\https://{your-app-domain}/{path}/{conversation-id}?{ts-query-params}` format. For example, `\https://myapp.example.com/analytics/shared/{conversation-id}?{ts-query-params}`. + ++ +When a user shares a conversation from an embedded Spotter interface, ThoughtSpot generates the recipient's link from the configured format string. On that page, your application reads the conversation ID from the URL and passes it to the embed in the `sharedConversationId` property of the `SpotterEmbed` configuration. The embed then opens the shared conversation directly in the read-only view and the recipient lands in the host application page defined in the template, with the shared conversation's ID in the URL path. For more information about the conversation sharing configuration, see xref:customize-spotter-sharing.adoc#_customizing_conversation_sharing_link[Customizing Spotter conversation sharing link]. + + [#genericLink] Generic link:: diff --git a/modules/ROOT/pages/customize-nav-full-embed.adoc b/modules/ROOT/pages/customize-nav-full-embed.adoc index b90c71995..05845b0b0 100644 --- a/modules/ROOT/pages/customize-nav-full-embed.adoc +++ b/modules/ROOT/pages/customize-nav-full-embed.adoc @@ -104,6 +104,31 @@ const embed = new AppEmbed("#embed", { == Command palette availability in embed In ThoughtSpot application, users can open the link:https://docs.thoughtspot.com/cloud/latest/thoughtspot-homepage#command-palette[command palette] by pressing kbd:[Cmd+K] on macOS or kbd:[Ctrl+K] on Windows to quickly navigate to objects and perform actions. However, when you embed ThoughtSpot, this feature is disabled and embedded pages include only the standard object search experience. +== Navigate to the Collections page + +To set the Collections page as the default landing page for full application embedding, use `Page.Collections` in the `pageId` property of `AppViewConfig`. + +// SOURCE: https://github.com/thoughtspot/visual-embed-sdk/blob/master/src/embed/app.ts + +[source,JavaScript] +---- +import { AppEmbed, Page } from '@thoughtspot/visual-embed-sdk'; + +const embed = new AppEmbed('#tsEmbed', { + // ... other embed view config + pageId: Page.Collections, + showPrimaryNavbar: true, +}); +embed.render(); +---- + +You can also use `navigateToPage` to route users to the Collections page programmatically after the app loads: + +[source,JavaScript] +---- +appEmbed.navigateToPage('collections'); +---- + == Customize the left navigation panel on the home page In the V3 and V4 experience modes, the left navigation panel on the *Insights* > *Home* page includes menu items such as *Spotter*, *Answers*, *Liveboards*, *SpotIQ Analysis*, *Monitor Subscriptions*, and more. You can hide this navigation panel by setting the `hideHomepageLeftNav` property to `true` in the SDK. Note that this attribute hides the left navigation only on the home page. @@ -181,6 +206,11 @@ To show or hide the *Scheduled Liveboards* section in the | [tag greenBackground tick]#✓# Supported | [tag greenBackground tick]#✓# Supported +| `HomeLeftNavItem.Collections` + +#To show or hide the *Collections* menu item in the *Insights* left navigation panel.# +| [tag greenBackground tick]#✓# Supported +| [tag greenBackground tick]#✓# Supported + |==== diff --git a/modules/ROOT/pages/customize-spotter-analysts.adoc b/modules/ROOT/pages/customize-spotter-analysts.adoc new file mode 100644 index 000000000..2c2a8ad59 --- /dev/null +++ b/modules/ROOT/pages/customize-spotter-analysts.adoc @@ -0,0 +1,94 @@ += Configure Spotter Analysts +:toc: true +:toclevels: 2 + +:page-title: Customizing Spotter Analysts in the embedded view +:page-pageid: customize-spotter-analysts +:page-description: You can customize the Spotter Analysts panel and dashboard using the customization options available in the Visual Embed SDK. + +Spotter Analysts are use-case-scoped AI analysts that bring governed, pre-configured natural language analytics to your embedded applications. + +== Overview +Instead of showing a blank Spotter prompt and expecting users to pick the right data source and ask the correct questions to get the right answers, you can provide them with a pre-configured, governed Analyst that is scoped with the right data context. With the data pre-scoped to what the team is allowed to access and the tools governed accordingly, every team member gets the same context without having to configure anything themselves. + +ThoughtSpot allows users to create and manage link:https://docs.thoughtspot.com/cloud/latest/spotter-analysts[Analysts, window=_blank] directly within the Spotter interface. Each Analyst is scoped to a data model and can be configured with custom instructions, tool restrictions, and conversation starter options. You can also set share permissions and administrative controls to determine who can access or modify the Analyst in the embedded view. + +[#_spotter_analysts] +== Spotter Analysts in the embedded view +When Spotter Analysts are enabled on your ThoughtSpot instance and xref:customize-spotter-sidebar.adoc[sidebar] is visible in the embedded view, the Analysts panel and dashboard are visible by default. The sidebar also includes the option to view a specific Analyst or open the dashboard to view all the available Analysts. + +=== Customizing the Analyst panel visibility +To control the visibility of the Spotter Analysts panel in the embedded sidebar, use the `SpotterAnalystSidebar` action ID in the `disabledActions` or `hiddenActions` array. + +The following example shows how to hide the Spotter Analysts panel from the embedded view: + +[source,JavaScript] +---- +const embed = new SpotterEmbed("#embed", { + // ...other Spotter embed configuration options + disabledActions: [ + Action.SpotterAnalystSidebar, + ], +}); +---- + +=== Control individual Analyst actions +When Analysts are enabled in the embedded view, you can show or hide specific menu actions using the following action IDs: + +[cols="1,3", options="header"] +|=== +| Action ID | Description + +| `Action.CreateAnalyst` +| Action ID for the *Create new* action for creating a new Spotter Analyst. + +| `Action.EditAnalyst` +| Action ID for the edit option for an existing Analyst. + +| `Action.CopyAnalyst` +| Action ID for the *Make a copy* action for duplicating an Analyst. + +| `Action.ShareAnalyst` +| Action ID for the share action for sharing an Analyst with other users. + +| `Action.DeleteAnalyst` +| Action ID for the delete option for removing an Analyst. +|=== + +[source,JavaScript] +---- +const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { + // ...other embed view configuration options + hiddenActions: [ + Action.DeleteAnalyst, + ], +}); +---- + +=== Customizing label strings +If you want to replace the default "Analyst" or "Analysts" text with terminology that matches your application, use the `spotterAnalystLabel` and `spotterAnalystsLabel` locale customization strings. + +For example, you might want to use "AI Assistant" instead of "Analyst" in your embedded application: + +[source,JavaScript] +---- +const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { + // ...other embed view configuration options + spotterSidebarConfig: { + // show sidebar panel + enablePastConversationsSidebar: true, + // Custom label for a single Analyst (default: "Analyst") + spotterAnalystLabel: 'AI Assistant', + // Custom label for the Analysts section heading (default: "Analysts") + spotterAnalystsLabel: "AI assistants", + }, +}); +---- + +== Additional resources +* link:https://docs.thoughtspot.com/cloud/latest/spotter-analysts[Spotter Analysts in product documentation, window=_blank] +* xref:customize-spotter-embed.adoc[Customizing the Spotter embed view] +* xref:api-changelog.adoc[Visual Embed SDK changelog] +* xref:customize-spotter-sidebar.adoc[Customizing the Spotter sidebar panel] + + diff --git a/modules/ROOT/pages/customize-spotter-chat-experience.adoc b/modules/ROOT/pages/customize-spotter-chat-experience.adoc new file mode 100644 index 000000000..bc929124a --- /dev/null +++ b/modules/ROOT/pages/customize-spotter-chat-experience.adoc @@ -0,0 +1,293 @@ += Customize the Spotter chat experience +:toc: true +:toclevels: 2 + +:page-title: Customizing the Spotter chat experience +:page-pageid: customize-spotter-chat-experience +:page-description: You can customize the Spotter chat panel and conversational experience using the customization options available in the Visual Embed SDK. + +You can customize the chat panel and conversational experience using the customization controls available in the xref:SpotterEmbedViewConfig.adoc[SpotterEmbedViewConfig] and xref:SpotterChatViewConfig.adoc[SpotterChatViewConfig] interfaces. + +== Spotter chat interface +The chat experience in the embedded view varies according to the Spotter experience enabled in your Spotter embed. + +[width="100%" cols="5,7,7"] +[options="header"] +|==== +|Feature |Description |Availability + +|Data model selector +|Allows users to select a data model to set the context for their Spotter query. +Supports setting *All data models* to let Spotter automatically determine and select the data source. + +| +[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +|Toggle to switch between Quick search and Deep analysis mode + +|Allows users to switch between the Quick search and Deep analysis mode in the Spotter interface. + +|[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +|Add files + +|Allows users to add files from their local directory to provide context for a Spotter query. Available under the *+* icon in the chat input area. + +| +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +|Connectors context + +|Allows users to add external connectors and set context for user queries based on the resources from these connectors. + + +In the new Spotter experience, this option is available under the *+* icon in the chat panel. + +| +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic +|Spotter starter prompts + +a|Preconfigured search questions that guide users by displaying clickable suggestion pills in the Spotter chat interface. Includes the following prompt pills: + +* Quick search +* Deep Analysis +* Know your data + +a| +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +|==== + +== Data model selection +To load the Spotter interface with a pre-selected data source, you must specify the data context in the `worksheetId` attribute. You can specify the GUID of the data model or `auto_mode` in the `worksheetId` attribute to enable *All data models* option so that Spotter can automatically discover and select a relevant data model for user queries. + +[source,JavaScript] +---- +const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { + worksheetId: "auto_mode", + // ...other embed configuration attributes +}); +---- + +== Quick search and deep analysis mode +With Spotter 2 and Spotter 3 experience enabled in the embedded view, the Spotter page displays a toggle switch to allow users to switch between the link:https://docs.thoughtspot.com/cloud/latest/spotter-research-mode[quick search and deep analysis modes]. + +To show, hide, or disable this feature, use the action ID, `Action.SpotterChatModeSwitcher`. + +[source,JavaScript] +---- +const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { + // ...other embed view configuration options + hiddenActions: [ + Action.SpotterChatModeSwitcher, + ], +}); +---- + +== Spotter starter prompts +Spotter starter prompts are preconfigured search questions that guide users when they first interact with Spotter. They provide curated starting points for data exploration by displaying clickable suggestion pills that help users understand what types of questions they can ask about their data. The starter prompts can be found below the prompt panel in the embedded Spotter page. + +Starter prompts can be automatically created by ThoughtSpot based on your data model or manually configured by developers to address specific business needs. The prompts are data-model-specific and their content dynamically changes according to the data source content being used by the user for their interaction with Spotter. + +=== Types of starter prompts +When included in the embedded interface, the Spotter page displays the following starter prompts pills: + +* *Quick search* + +Includes common queries that users frequently ask. These prompts help users get quick answers to standard business questions, such as top products, sales summaries, or regional breakdowns. + +* *Deep analysis* + +Includes complex analytical questions that require deeper investigation. These prompts guide users toward more sophisticated analysis, such as trend analysis, correlation studies, or root-cause analysis. + +* *Know your data* + +Users can use this feature to understand the data available to them. This category is useful for onboarding new users or introducing new datasets. + +=== Enabling Starter prompts in the embedded view +To enable starter prompts in the embedded page, set the `enableStarterPrompts` property in the `spotterChatConfig` object to `true`. + +[source,JavaScript] +---- +const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { + // ...other embed view configuration options + spotterChatConfig: { + enableStarterPrompts: true, + }, +}); +---- + +//// +=== Customizing prompt pills and their contents +To customize the prompt pills and their contents, use the following properties in the `starterPrompts` object: + +* `quick` for the Quick search pill +* `research` for the Deep analysis pill +* `previewData` for the Know your data pill. + +The SDK allows you to customize the following properties of the starter prompt pills: + +* `label` + +__String__. Overrides the default pill label. +* `questions` + +__Array of strings__. For each question entry, you can customize the question label and add your own prompt text. Any entry without the `prompt` value is dropped. + +[IMPORTANT] +==== +For the `previewData` category, you can customize only the prompt pill `label` string. +==== + +==== Example + +[source,JavaScript] +---- +const embed = new SpotterEmbed('#tsEmbed', { + // ...other embed view configuration options + spotterChatConfig: { + enableStarterPrompts: true, + starterPrompts: { + quick: { + label: 'Sample questions', + questions: [ + { + label: 'Top products', + prompt: 'What are the top products by revenue?', + }, + ], + }, + research: { + label: 'Deep analysis', + questions: [ + { + label: 'Revenue drivers', + prompt: 'Analyze the main drivers of revenue changes', + }, + ], + }, + previewData: { + label: 'Explore your data', + }, + }, + }, +}); +---- + +=== Customizing the visibility of prompt pills +If you want to include or exclude any specific prompt pill, use the following action IDs with the `hiddenActions` or `visibleActions` array to control the visibility. + +* `Action.QuickSearchPill` for *Quick search* +* `Action.DeepAnalysisPill` for *Deep analysis* +* `Action.DataLiteracyPill` for *Know your data* + +[source,javascript] +---- +const embed = new SpotterEmbed('#tsEmbed', { + // ...other embed view configuration options + spotterChatConfig: { + enableStarterPrompts: true, + }, + hiddenActions: [Action.DeepAnalysisPill] +}); +---- +//// + + +[#fileUpload] +== File uploads in Spotter chats +The **Add files** option is available in the embedded view by default if your embed has Spotter 2 or Spotter 3 experience enabled. + +To customize the visibility of the **Add files** option, use `spotterFileUploadEnabled` in the `spotterChatConfig` object. + +You can also restrict the types of files users can upload by specifying file format in the `spotterFileUploadFileTypes` array. If no file format is specified, all supported file types are allowed for uploads. + +[source,JavaScript] +---- +const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { + // ...other embed configuration attributes + updatedSpotterChatPrompt: true, + spotterChatConfig: { + spotterFileUploadEnabled: true, + spotterFileUploadFileTypes: ['pdf', 'png', 'xlsx'], + }, +}); +---- + +[#mcp-connectors] +== MCP connectors and resource selection +The ability to select external MCP connectors and resources for Spotter AI analytics is available when Spotter 3 experience is enabled in the embedded view. This integration allows your application users to include both structured and unstructured data in their conversation sessions. + +The **Manage connectors** icon in the chat panel allows users to select external connectors such as Google Drive, Slack, Notion, Confluence, Web search or Jira, as a data sources in their Spotter sessions. This list displays only the connectors that are preconfigured by the ThoughtSpot administrator. + +To show, hide, or disable the **Manage connectors** option, use the `Action.SpotterChatConnectors` action ID in the `hiddenActions` or `disabledActions` array. + +[source,JavaScript] +---- +const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { + // ...other embed view configuration options + updatedSpotterChatPrompt: true, + hiddenActions: [ + Action.SpotterChatConnectors + ], +}); +spotterEmbed.render(); +---- + +== Spotter icon customization +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] +---- + 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" + } + }); +---- + +The following figures show the customized Spotter icon: +[.widthAuto] +[.bordered] +image::./images/spotter-icon-customization.png[Spotter icon customization] + +== Spotter logo and ThoughtSpot branding label +To hide the Spotter logo and branding in the chat interface and tool response, use the following `SpotterChatViewConfig` object properties: + +* `hideToolResponseCardBranding` + +When set to `true`, hides the ThoughtSpot logo and icon in tool response cards. The branding label prefix is controlled separately via `toolResponseCardBrandingLabel`. + +* `toolResponseCardBrandingLabel` + +Custom label to replace the `ThoughtSpot` prefix in tool response cards. Set to an empty string (`''`) to hide the prefix entirely. + +Example:: ++ +[source,JavaScript] +---- +import { + SpotterEmbed, + SpotterEmbedViewConfig, + SpotterChatViewConfig +} from '@thoughtspot/visual-embed-sdk'; + +const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { + // ...other embed view configuration options + spotterChatConfig: { + // Hide the default logo and label on tool response cards in Spotter chat UI + hideToolResponseCardBranding: true, + // Set a custom label to display as the branding on tool response cards + toolResponseCardBrandingLabel: 'CompanyName', + }, +}); +---- + +== Additional resources +* xref:customize-spotter-embed.adoc[Customizing the Spotter embed view] +* xref:customize-spotter-sidebar.adoc[Customizing the Spotter sidebar panel] +* xref:customize-spotter-sharing.adoc[Customizing Spotter conversation sharing] +* xref:customize-spotter-analysts.adoc[Customizing Spotter Analysts in the embedded view] diff --git a/modules/ROOT/pages/customize-spotter-embed.adoc b/modules/ROOT/pages/customize-spotter-embed.adoc index 4dc6ed070..b4529fec6 100644 --- a/modules/ROOT/pages/customize-spotter-embed.adoc +++ b/modules/ROOT/pages/customize-spotter-embed.adoc @@ -1,4 +1,4 @@ -= Customizing the Spotter embed view += Customize the Spotter embed view :toc: true :toclevels: 2 @@ -6,289 +6,85 @@ :page-pageid: customize-spotter-embed :page-description: You can customize the SpotterEmbed experience using the customization options available in the Visual Embed SDK. -When you xref:embed-spotter.adoc[embed Spotter] in your application, 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 Visual Embed SDK provides a vast set of configuration settings and object properties to customize the Spotter UI and chat experience for your embedding application users. -== Spotter UI -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. +== Spotter interface in the embedded view +When you xref:embed-spotter.adoc[embed Spotter] in your application, you'll notice that the embedded component loads an initial page with a prompt interface. The look and feel of this page varies depending on the Spotter version used for embedding. -== Spotter 3 experience -Spotter 3 experience is available with a new prompt interface that includes additional features and user elements to enrich your Spotter experience. +=== Default experience +The default experience in embedded view is the classic Spotter interface with an initial page that includes a prompt bar for user input, a data source selector, and the UI options to preview data and reset a Spotter session. ++ +If Spotter 2 is enabled on your ThoughtSpot instance, additional controls such as Quick search and Deep analysis toggle switch, and the automatic data model selection option are available. ++ +[.widthAuto] +[.bordered] +image::./images/spotter-default-interface.png[Default Spotter interface] -To enable the new chat interface in your embed, set the `updatedSpotterChatPrompt` attribute: +=== Spotter 3 experience +If your ThoughtSpot instance has Spotter 3 experience enabled, you can enable the same experience in your embed, which includes additional options to add files, connectors, and improved conversational experience. To enable Spotter 3 experience, set `updatedSpotterChatPrompt` to `true` in the SDK. [source,JavaScript] ---- const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { - // ...other embed configuration attributes + worksheetId: '', // Replace with GUID of the data source // Enable the updated Spotter chat prompt experience. updatedSpotterChatPrompt: true, + // Show chat history panel + spotterSidebarConfig: { + enablePastConversationsSidebar: true, + }, + // ...other embed configuration attributes }); ---- [.widthAuto] [.bordered] -image::./images/spotter3-new-interface.png[Spotter 3 new interface] +image::./images/spotter3-interface.png[Spotter 3 experience] -=== Spotter classic and Spotter 2 - -[.widthAuto] -[.bordered] -image::./images/spotter-embed-legacy.png[Spotter embed] - -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. -==== - -=== Chat history panel -You can also include the *Chat history* panel to allow your users to access the chat history from their previous sessions. To enable and customize the chat history sidebar, configure the chat history properties in the `spotterSidebarConfig` object: +=== New Spotter 3 visual experience +On instances with ThoughtSpot Cloud 26.9.0.cl, the new redesigned Spotter experience is enabled by default. The new Spotter experience includes the updated conversation layout and starter-prompt pills. To enable the new visual experience, set `updatedSpotterExperience` to `true` in the `SpotterEmbed` configuration. [source,JavaScript] ---- -import { - SpotterEmbed, - SpotterEmbedViewConfig, - SpotterSidebarViewConfig -} from '@thoughtspot/visual-embed-sdk'; - -const embed = new SpotterEmbed('#tsEmbed', { - // ...other embed view configuration options - // Configuration for the Spotter sidebar UI +const spotterEmbed = new SpotterEmbed('#ts-embed', { + worksheetId: '', // Replace with GUID of the data source + // Enable Spotter 3 chat experience. + updatedSpotterChatPrompt: true, + // Enable new Spotter visual experience + updatedSpotterExperience: true, + // Show chat history panel spotterSidebarConfig: { - enablePastConversationsSidebar: true, // Enable the chat history sidebar - spotterSidebarDefaultExpanded: true, // Expand the sidebar by default - spotterSidebarTitle: 'Chat History', // Custom sidebar header text - spotterNewChatButtonTitle: 'New Conversation', // Custom label for the New chat button - spotterChatRenameLabel: 'Rename session', // Custom label for the Rename action - spotterChatDeleteLabel: 'Delete session', // Custom label for the Delete action - spotterConversationsBatchSize: 20, // Conversations fetched per batch (default: 30) - spotterDocumentationUrl: 'https://your-help-center-url', // Custom best practices link - }, -}) ----- - -[NOTE] -==== -The standalone `enablePastConversationsSidebar` property on `SpotterEmbedViewConfig` is deprecated from Visual Embed SDK v1.47.0. Use the `enablePastConversationsSidebar` property within the `spotterSidebarConfig` object instead. When both properties are defined, the value in `spotterSidebarConfig` takes precedence. -==== - -== Spotter Analysts -ThoughtSpot allows users to create and manage AI agents (Analysts) directly within the Spotter interface. These AI agents or bots are referred to as link:https://docs.thoughtspot.com/cloud/latest/spotter-analysts[Spotter Analysts, window=_blank]. Each Analyst is scoped to a data model and can be configured with custom instructions, personas, and conversation starters. - -If you have Spotter Analysts on your ThoughtSpot instance, you can make these available to your embedding application users. - -=== Spotter Analyst panel -If your ThoughtSpot instance has Spotter Analysts, the Spotter Analysts panel and dashboard are visible by default in the Spotter sidebar in the embed view. To control the visibility of this panel in the embed view, use the `SpotterAnalystSidebar` action ID in the `disabledActions`, `hiddenActions`, or `visibleActions` arrays as needed. - -If Spotter Analysts are enabled in the embed view, you can use the following action IDs to show or hide the menu actions: - -* `Action.CreateAnalyst` + -Action ID for the **Create new** action in the Spotter Analysts page. -* `Action.EditAnalyst` + -Action ID for the Analyst edit option. -* `Action.CopyAnalyst` + -Action ID for the *Make a copy* action that creates a copy of the Analyst. -* `Action.ShareAnalyst` + -Action ID for the share action that allows sharing an Analyst with other users. -* `Action.DeleteAnalyst` + -Action ID for the delete option. - -[source,JavaScript] ----- -const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { - // ...other embed view configuration options - hiddenActions: [ - Action.CreateAnalyst, - Action.DeleteAnalyst, - ], -}); ----- - -=== Analysts label strings -Use `spotterAnalystLabel` and `spotterAnalystsLabel` to replace the default "Analyst" and "Analysts" label text in the embedded Spotter interface with custom terminology suited to your application: - -[source,JavaScript] ----- -const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { - // ...other embed view configuration options - // Custom label for a single Analyst (default: "Analyst") - spotterAnalystLabel: 'AI Assistant', - // Custom label for the Analysts section heading (default: "Analysts") - spotterAnalystsLabel: 'AI Assistants', -}); ----- - -== Quick search and deep analysis mode -When Spotter 3 experience is enabled on a ThoughtSpot instance, the Spotter interface displays a switcher to toggle between the Quick Search and Deep Analysis modes. - -To show, hide, or disable this feature in the embedded view, use the action ID, -`Action.SpotterChatModeSwitcher`. - -[source,JavaScript] ----- -const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { - // ...other embed view configuration options - hiddenActions: [ - Action.SpotterChatModeSwitcher, - ], -}); ----- - -== Spotter starter prompts -ThoughtSpot allows users to preselect prompts and display these prompts in the Spotter interface for quick analysis. This feature is disabled by default in the embedded view. To enable this feature, contact ThoughtSpot Support. - -When this feature is enabled on your instance, you can use the `enableStarterPrompts` property in the `spotterChatConfig` object to display the starter prompts to your embedding application users. These prompts appear below the search bar when the users open the Spotter embedded view. - -[source,JavaScript] ----- -const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { - // ...other embed view configuration options - spotterChatConfig: { - enableStarterPrompts: true, - }, -}); ----- - -[#mcp-connectors] -== MCP connectors and resource selection icon -If the Spotter 3 interface is enabled, the Spotter page displays the following options to connect external tools and resources for AI analytics. - -* Connector icon that allows you to connect to external applications such as Google Drive, Slack, Notion, Confluence, or Jira, which can be used as a data source in Spotter sessions. These connectors must be preconfigured by your ThoughtSpot administrator for your embedding deployments. -* Add files (+) icon for uploading files and resources for setting the conversation context. -* **Connectors** menu with a `+` icon in the prompt panel that lets your application users connect to external tools and resources. - -These integrations allow users to include both structured and unstructured data in their conversation sessions. - -To show, hide, or disable these options, use the following action IDs in the `disabledActions`, `hiddenActions`, or `visibleActions` arrays as needed: - -* `Action.SpotterChatConnectors` for the Connectors list. -* `Action.SpotterChatConnectorResources` for the connector resources section. - -[source,JavaScript] ----- -const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { - // ...other embed view configuration options - hiddenActions: [ - Action.SpotterChatConnectors, - Action.SpotterChatConnectorResources, - ], -}); -spotterEmbed.render(); ----- - -[#fileUpload] -== File uploads in Spotter chats -To enable file uploads in the Spotter chat panel: - -. Ensure that `spotterFileUploadEnabled` is set to `true` in the `spotterChatConfig` object. This setting enables the **+ Add files** option in the Spotter chat panel. -. Optionally, you can restrict the types of files users can upload by specifying the file types in the `spotterFileUploadFileTypes` array. If no file format is specified, all supported file types are allowed for uploads. - -[source,JavaScript] ----- -const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { - //... - spotterChatConfig: { - spotterFileUploadEnabled: true, - spotterFileUploadFileTypes: ['pdf', 'png', 'xlsx'], - }, -}); ----- - -//// -For earlier SDK versions, you can use CSS selectors as a workaround: - -[source,JavaScript] ----- -init({ - 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 + enablePastConversationsSidebar: true, + }, + // ...other embed configuration attributes }); ---- -//// - -== Spotter icon customization -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] ----- - 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" - } - }); ----- -The following figures show the customized Spotter icon: [.widthAuto] [.bordered] -image::./images/spotter-icon-customization.png[Spotter icon customization] +image::./images/spotter-new-experience.png[New Spotter experience] -== Spotter logo and ThoughtSpot branding label -To hide the Spotter logo and branding in the chat interface and tool response, use the following `SpotterChatViewConfig` object properties: +In the new experience, the + icon displays a menu with the following options: -* `hideToolResponseCardBranding` + -When set to `true`, hides the ThoughtSpot logo and icon in tool response cards. The branding label prefix is controlled separately via `toolResponseCardBrandingLabel`. +* **Add files** from local directory +* **Connectors** to select available connectors +* **Deep analysis** toggle to switch between the quick search and research mode. -* `toolResponseCardBrandingLabel` + -Custom label to replace the `ThoughtSpot` prefix in tool response cards. Set to an empty string (`''`) to hide the prefix entirely. +You can customize the chat panel and conversational experience further. For more information, see xref:customize-spotter-chat-experience.adoc[Customizing the Spotter chat experience]. -Example:: -+ -[source,JavaScript] ----- -import { - SpotterEmbed, - SpotterEmbedViewConfig, - SpotterChatViewConfig -} from '@thoughtspot/visual-embed-sdk'; +== Customizing Spotter experience +If you want to customize specific features or UI elements, refer to the following documentation: -const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { - // ...other embed view configuration options - spotterChatConfig: { - // Hide the default logo and label on tool response cards in Spotter chat UI - hideToolResponseCardBranding: true, - // Set a custom label to display as the branding on tool response cards - toolResponseCardBrandingLabel: 'CompanyName', - }, -}); ----- +* xref:customize-spotter-chat-experience.adoc[Customizing the Spotter chat experience] + +For information on customizing the chat panel, data model selection, starter prompts, file uploads, MCP connectors, and Spotter branding. +* xref:customize-spotter-sidebar.adoc[Customizing the Spotter sidebar panel] + +For information on customizing the sidebar panel and the chat history panel, including menu actions and app interactions. +* xref:customize-spotter-sharing.adoc[Customizing Spotter conversation sharing] + +For information on customizing the conversation sharing experience, sharing links, and app interactions. +* xref:customize-spotter-analysts.adoc[Customizing Spotter Analysts in the embedded view] + +For information on customizing the Spotter Analysts panel and dashboard. -== Styles and interface elements +== Customizing styles and interface elements using CSS variables 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. @@ -320,7 +116,7 @@ init({ }); ---- -=== Text string customization +=== Customizing text strings To replace text strings, you can use the `stringIDs` and `strings` properties in the content customization object. The following example shows how to replace "Spotter" and other text strings on the Spotter interface. @@ -334,8 +130,6 @@ init({ 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", } @@ -344,26 +138,20 @@ init({ }); ---- +//// [#spotterMenuActions] === Menu elements and action visibility 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: +For a comprehensive list of supported actions, see the xref:Action.adoc[Action reference documentation]. +//// -[source,JavaScript] ----- - // 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]. == Additional resources -* xref:embed-ai-analytics.adoc[Spotter features and embedding options] +* xref:customize-spotter-chat-experience.adoc[Customizing the Spotter chat experience] +* xref:customize-spotter-sidebar.adoc[Customizing the Spotter sidebar panel] +* xref:customize-spotter-sharing.adoc[Customizing Spotter conversation sharing] +* xref:customize-spotter-analysts.adoc[Customizing Spotter Analysts in the embedded view] * 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] diff --git a/modules/ROOT/pages/customize-spotter-sharing.adoc b/modules/ROOT/pages/customize-spotter-sharing.adoc new file mode 100644 index 000000000..07dfa6676 --- /dev/null +++ b/modules/ROOT/pages/customize-spotter-sharing.adoc @@ -0,0 +1,192 @@ += Customize conversation sharing experience +:toc: true +:toclevels: 2 + +:page-title: Customizing Spotter conversation sharing +:page-pageid: customize-spotter-sharing +:page-description: You can customize the Spotter conversation sharing experience using the customization options available in the Visual Embed SDK. + +Users can share their Spotter conversations with other users and groups from the embedded Spotter interface. + +[#_spotter_conversation_sharing] +== Spotter conversation sharing experience +Conversation sharing is turned off by default in embedded Spotter interface. To enable it, set `enableShareConversation` to `true` in the `spotterShareConversationConfig` object. This setting enables the *Share* action in the Spotter response page and the chat history panel in the sidebar, which allows a user to share a conversation with other users and groups in their application. The recipients can access a shared conversation only in a read-only view. + +[source,JavaScript] +---- +const spotterEmbed = new SpotterEmbed('#ts-embed', { + // Enable conversation sharing + spotterShareConversationConfig: { + enableShareConversation: true, + }, + // ...other embed view configuration options +}); +---- + +== Customizing share modal and sharing settings +To customize the conversation sharing experience, use the following options in +the `SpotterShareConversationConfig` interface as needed: + +[width="100%", cols="5,7"] +[options='header'] +|===== +|Property |Description +|`enableShareConversation` |Enables conversation sharing in the embedded interface. Default is `false`. +|`spotterShareLabel` |Label of the *Share* button in the conversation header and the *Share* menu item in the sidebar. Default text is `Share`. +|`spotterShareModalTitle` | Title of the share modal. +|`spotterShareConfirmLabel` |Label of the confirm button in the share modal. Default label is `Share`. +|`spotterShareCancelLabel` |Label of the cancel button in the share modal. Default label is `Cancel`. +|`spotterShareAddUsersLabel` |Label of the recipient picker in the share modal. +|`spotterShareEmptyTitle` |Title text shown when the recipient picker is empty. +|`spotterShareEmptySubtitle` |Subtitle text shown when the recipient picker is empty. +|`spotterShareIncludeNewMessagesLabel` |Label of the checkbox that includes messages added since the last shared version. +|`spotterShareUpToCurrentLabel` |Footer note shown in the share modal when the shared snapshot is current. +|`spotterShareStaleInfoLabel` |Banner text shown in the share modal when the shared snapshot is stale. +|`spotterSharedConversationBannerMessage` |Data-access banner text shown in the read-only shared view. +|`spotterSharedConversationExitLabel` |Label of the *Exit* button in the read-only shared view. Default label is `Exit`. +|| +|===== + +[source,JavaScript] +---- +const spotterEmbed = new SpotterEmbed('#ts-embed', { + // Enable conversation sharing + spotterShareConversationConfig: { + enableShareConversation: true, + spotterShareAddUsersLabel: "Add recipients", + spotterShareIncludeNewMessagesLabel: "Include new messages", + }, + // ...other embed view configuration options +}); +---- + +== Customizing conversation sharing link +When a user shares a conversation from an embedded Spotter interface, the share link sent to recipients must open within your embedding application context and not direct recipients to the conversation page in the ThoughtSpot instance. + +To customize the URL for your application context, configure the conversation share link setting and then pass the conversation ID to your embed. + +=== Configure the conversation share link setting +To customize the conversation share link format: + +. Go to **Develop** > **Link settings** page in your ThoughtSpot application. +. Specify the conversation share link URL so that the links are generated in a URL format that is customized for your application's domain URL, with a placeholder for the shared conversation's ID. ++ +`\https://{your-app-domain}/{path}/{conversation-id}?{ts-query-params}` + ++ +For example: +`\https://myapp.example.com/analytics/shared/{conversation-id}?{ts-query-params}` + +If the conversation sharing link format is defined, ThoughtSpot replaces the `{conversation-id}` with the ID of the shared conversation and generates the link in the specified URL format, so the recipient is directed to the shared conversation page within their application context. + +For more information about customizing links in embedded deployments, see xref:customize-links.adoc[Customize links]. + +=== Pass the conversation ID to your embed +When the user shares a conversation, add the necessary code in your application to read the conversation ID from the page URL and pass it to `SpotterEmbed` in the `sharedConversationId` property. + +[source,JavaScript] +---- +const convId = new URLSearchParams(window.location.search).get('conversation-id'); +const embed = new SpotterEmbed('#tsEmbed', { + //... other embed view config + spotterShareConversationConfig: { + enableShareConversation: true, + }, + sharedConversationId: convId, +}) +---- + +When the `sharedConversationId` property is configured, the embed opens the shared conversation directly in the read-only view, for all recipients within your application. + +== Customizing the visibility of sharing UI elements +Use the following `Action` enum members in `hiddenActions` or `disabledActions` to control individual sharing UI elements: + +* `Action.SpotterShareConversationButtonHeader` for **Share** button in the Spotter conversation header. +* `Action.SpotterShareConversationMenuItemSidebar` for **Share** menu action in the chat history panel in the sidebar. +* `Action.SpotterShareIncludeNewMessagesCheckbox` for the `include new messages since last shared version` checkbox in the share modal. +* `Action.SpotterSharedConversationBannerDismissButton` for the dismiss button of the data access banner displayed in the shared conversation view. +* `Action.SpotterShareUpToCurrentInfo` for the share modal footer note, "Chat will be shared up to the current moment…." +* `Action.SpotterSharedConversationBanner` for the data access banner shown when a recipient opens a shared conversation. +* `Action.SpotterShareStaleInfoBannerDismissButton` for the banner that shows the message, "This data may have changed since the last time you had a chat." +* `Action.SpotterSharedConversationExitButton` for *Exit* button in the read-only view of the shared conversation. + ++ +[source,JavaScript] +---- +const spotterEmbed = new SpotterEmbed('#ts-embed', { + worksheetId: '', + spotterShareConversationConfig: { + enableShareConversation: true, + }, + // Allow sharing from the header only; hide the sidebar entry point + hiddenActions: [Action.SpotterShareConversationMenuItemSidebar,Action.SpotterShareUpToCurrentInfo], +}); +---- + +For a complete list of action IDs, see xref:Action.adoc[Action reference]. + +== Customizing app interactions + +Use the following event IDs to enable interaction between the host and the embedded application: + +HostEvents:: +* `HostEvent.ShareSpotterConversation` + +Opens the Spotter share conversation modal for the given conversation ID. +* `HostEvent.ExitSpotterSharedConversation` + +Exits the read-only view of the shared conversation. +* `HostEvent.CloseSpotterShareConversation` + +Closes the Spotter share conversation modal. + ++ +[source,JavaScript] +---- +spotterEmbed.trigger(HostEvent.ShareSpotterConversation, { + conversationId: '', +}); +---- + ++ +For a complete list of event IDs, see xref:HostEvent.adoc[HostEvent reference]. + +EmbedEvents:: + +* `EmbedEvent.SpotterConversationShared` + +Emitted when a Spotter conversation is shared with the intended recipients. +* `EmbedEvent.SpotterConversationShareRevoked` + +Emitted when access to a shared Spotter conversation is revoked. +* `EmbedEvent.SpotterSharedConversationViewed` + +Emitted when a recipient opens a shared Spotter conversation. +* `EmbedEvent.SpotterShareConversationButtonHeaderClicked` + +Emitted when the Share button in the conversation header is clicked. +* `EmbedEvent.SpotterShareConversationMenuItemSidebarClicked` + +Emitted when the Share action in the menu displayed for a chat in the chat history sidebar is clicked. +* `EmbedEvent.SpotterShareIncludeNewMessagesCheckboxToggled` + +Emitted when the user toggles the "include new messages since last shared version" checkbox in the share modal. +* `EmbedEvent.SpotterShareModalCancelButtonClicked` + +Emitted when the Cancel button in the share conversation modal is clicked. +* `EmbedEvent.SpotterShareStaleInfoBannerDismissed` + +Emitted when the user dismisses the banner that shows the text, "This data may have changed since the last time you had a chat." +* `EmbedEvent.SpotterSharedConversationExitButtonClicked` + +Emitted when a user exits the shared conversation read-only view. + ++ +[source,JavaScript] +---- +spotterEmbed.on(EmbedEvent.SpotterConversationShared, (payload) => { + console.log('Shared:', payload.shareId, payload.recipientsAdded); +}); + +spotterEmbed.on(EmbedEvent.SpotterConversationShareRevoked, (payload) => { + if (payload.fullyRevoked) { + console.log('All recipients removed'); + } +}); +---- + +For a complete list of event IDs, see xref:EmbedEvent.adoc[EmbedEvent reference]. + +== Additional resources +* xref:customize-spotter-embed.adoc[Customizing the Spotter embed view] +* xref:customize-spotter-chat-experience.adoc[Customizing the Spotter chat experience] +* xref:customize-spotter-sidebar.adoc[Customizing the Spotter sidebar panel] +* xref:customize-spotter-analysts.adoc[Customizing Spotter Analysts in the embedded view] diff --git a/modules/ROOT/pages/customize-spotter-sidebar.adoc b/modules/ROOT/pages/customize-spotter-sidebar.adoc new file mode 100644 index 000000000..288eee572 --- /dev/null +++ b/modules/ROOT/pages/customize-spotter-sidebar.adoc @@ -0,0 +1,166 @@ += Customize the Spotter sidebar panel +:toc: true +:toclevels: 2 + +:page-title: Customizing the Spotter sidebar panel +:page-pageid: customize-spotter-sidebar +:page-description: You can customize the sidebar panel in the Spotter embed, including the chat history panel, using the customization options available in the Visual Embed SDK. + +You can customize the Spotter sidebar panel and its contents using configuration properties available in the xref:SpotterSidebarViewConfig.adoc[SpotterSidebarViewConfig] interface. + +== Sidebar elements in the embedded view +The sidebar panel in the Spotter interface includes the following elements: + +[width="100%", cols="5,7,7"] +[options='header'] +|==== +|Feature |Description |Availability + +|Chat history sidebar + +|Allows users to access past chats from a sidebar and start a new conversation session. The chat history panel is disabled by default in the embedded view. +| +[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag greenBackground tick]#✓# Spotter Classic + +|Spotter Analysts + +|Allows users to view the Spotter Analysts in the sidebar panel and open the Analysts dashboard. This feature is available by default in the embedded view. +For more information, see xref:customize-spotter-analysts.adoc[Customizing Spotter Analysts in the embedded view]. + +| +[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag greenBackground tick]#✓# Spotter Classic + +|Spotter best practices + +|Provides users with guidance and best practices for using Spotter effectively. + +| +[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag greenBackground tick]#✓# Spotter Classic +|==== + +== Chat history panel +To allow your users to access the chat history from their previous sessions, you can enable the *Chat history* in the sidebar by setting the `enablePastConversationsSidebar` parameter to `true` in the `spotterSidebarConfig` object. You can also customize the default state and the labels as shown in this example: + +[source,JavaScript] +---- +const embed = new SpotterEmbed('#tsEmbed', { + // ...other embed view configuration options + // Configuration for the Spotter sidebar UI + spotterSidebarConfig: { + enablePastConversationsSidebar: true, // Enable the chat history sidebar + spotterSidebarDefaultExpanded: true, // Expand the sidebar by default + spotterSidebarTitle: 'Chat History', // Custom sidebar header text + spotterNewChatButtonTitle: 'New Conversation', // Custom label for the New chat button + spotterChatRenameLabel: 'Rename session', // Custom label for the Rename action + spotterChatDeleteLabel: 'Delete session', // Custom label for the Delete action + spotterConversationsBatchSize: 20, // Conversations fetched per batch (default: 30) + }, +}) +---- + +[NOTE] +==== +The standalone `enablePastConversationsSidebar` property on `SpotterEmbedViewConfig` is deprecated from Visual Embed SDK v1.47.0. Use the `enablePastConversationsSidebar` property within the `spotterSidebarConfig` object instead. When both properties are defined, the value in `spotterSidebarConfig` takes precedence. +==== + +=== Customizing sidebar menu actions +Use the following `Action` enum members in `hiddenActions` or `disabledActions` to control the visibility of individual chat history panel elements: + +* `Action.SpotterSidebarHeader` for the sidebar header, which includes the title and the expand/collapse toggle. Hide-only. +* `Action.SpotterSidebarToggle` for the expand/collapse toggle button on the sidebar. +* `Action.SpotterNewChat` for the *New Chat* button. +* `Action.SpotterPastChatBanner` for the past-conversation alert banner. Hide-only. +* `Action.SpotterChatMenu` for the three-dot edit menu displayed for each conversation in the list. +* `Action.SpotterChatRename` for the *Rename* option in the conversation edit menu. +* `Action.SpotterChatDelete` for the *Delete* option in the conversation edit menu. + ++ +[source,JavaScript] +---- +const spotterEmbed = new SpotterEmbed('#ts-embed', { + worksheetId: '', + spotterSidebarConfig: { + enablePastConversationsSidebar: true, + }, + // Hide the Rename option and the past-conversation banner + hiddenActions: [Action.SpotterChatRename, Action.SpotterPastChatBanner], +}); +---- + +For a complete list of action IDs, see xref:Action.adoc[Action reference]. + +=== Customizing app interactions +Use the following event IDs to enable interaction between the host application and the chat history panel: + +HostEvents:: +* `HostEvent.StartNewSpotterConversation` + +Starts a new Spotter conversation programmatically. + ++ +[source,JavaScript] +---- +spotterEmbed.trigger(HostEvent.StartNewSpotterConversation); +---- + ++ +For a complete list of event IDs, see xref:HostEvent.adoc[HostEvent reference]. For the host event that opens the share modal from the chat history panel, see xref:customize-spotter-sharing.adoc#_customizing_app_interactions[Customizing app interactions]. + +EmbedEvents:: + +* `EmbedEvent.SpotterConversationRenamed` + +Emitted when a user renames a conversation from the chat history panel. The event payload includes the `convId`, `oldTitle`, and `newTitle`. +* `EmbedEvent.SpotterConversationDeleted` + +Emitted when a user deletes a conversation from the chat history panel. The event payload includes the `convId` and `title`. +* `EmbedEvent.SpotterConversationSelected` + +Emitted when a user selects a conversation from the chat history panel. The event payload includes the `convId`, `title`, and `worksheetId`. + ++ +[source,JavaScript] +---- +spotterEmbed.on(EmbedEvent.SpotterConversationRenamed, (payload) => { + console.log('Renamed:', payload.convId, payload.oldTitle, '->', payload.newTitle); +}); + +spotterEmbed.on(EmbedEvent.SpotterConversationDeleted, (payload) => { + console.log('Deleted:', payload.convId, payload.title); +}); + +spotterEmbed.on(EmbedEvent.SpotterConversationSelected, (payload) => { + console.log('Selected:', payload.convId, payload.title, payload.worksheetId); +}); +---- + +For a complete list of event IDs, see xref:EmbedEvent.adoc[EmbedEvent reference]. + +== Customizing other settings in the sidebar panel +The other settings in the sidebar panel include a link to Best practices guide and the sidebar footer. + +To customize these options or to control their visibility in the sidebar, use the following options: + +* `spotterDocumentationUrl` + +Allows customizing the documentation link. +* `Action.SpotterSidebarFooter` + +Action ID to show or hide the sidebar footer that contains the documentation link. +* `Action.SpotterDocs` + +Action ID to show or hide the documentation or best practices link in the sidebar footer. + +[source,JavaScript] +---- +const embed = new SpotterEmbed('#tsEmbed', { + // ...other embed view configuration options + // Configuration for the Spotter sidebar UI + spotterSidebarConfig: { + enablePastConversationsSidebar: true, // Enable the chat history sidebar + spotterDocumentationUrl: 'https://your-help-center-url', // Custom best practices link + }, +}) +---- + +== Additional resources +* xref:customize-spotter-embed.adoc[Customizing the Spotter embed view] +* xref:customize-spotter-chat-experience.adoc[Customizing the Spotter chat experience] +* xref:customize-spotter-sharing.adoc[Customizing Spotter conversation sharing] +* xref:customize-spotter-analysts.adoc[Customizing Spotter Analysts in the embedded view] diff --git a/modules/ROOT/pages/customize-style.adoc b/modules/ROOT/pages/customize-style.adoc index 8f9d7c374..56f6b7316 100644 --- a/modules/ROOT/pages/customize-style.adoc +++ b/modules/ROOT/pages/customize-style.adoc @@ -9,6 +9,7 @@ If you want to match the look and feel of embedded ThoughtSpot content with your core application, you can customize the ThoughtSpot application UI elements. Using style customization, you can create a uniform ThoughtSpot experience that complies with your company's branding guidelines. You can rebrand the ThoughtSpot interface elements such as the application logo, background color, and color scheme of visualizations. + [NOTE] ==== When you rebrand ThoughtSpot content, the UI styles are reset for all users. @@ -185,13 +186,7 @@ To change the color palette for charts: . To access the ThoughtSpot Developer portal, click *Develop* . Under *Customizations*, click *Styles*. . Click the color box under *Chart Color Palettes*. -+ -image::./images/chart-colors.png[Chart Color Palettes] - . To choose a primary color, click the color box. -+ -image::./images/select-color.png[Select Primary Color] - . You can also add a HEX color code. . To add more colors, click *Add Color*. . To reset your chart colors to the ThoughtSpot default, click *Reset*. diff --git a/modules/ROOT/pages/data-apis-v2.adoc b/modules/ROOT/pages/data-apis-v2.adoc new file mode 100644 index 000000000..bf259489d --- /dev/null +++ b/modules/ROOT/pages/data-apis-v2.adoc @@ -0,0 +1,334 @@ += Data APIs +:toc: true +:toclevels: 3 + +:page-title: data-apis +:page-pageid: fetch-data-and-report-apis +:page-description: Data APIs + +ThoughtSpot provides the following REST API v2 endpoints to fetch data: + +* xref:#_search_data_api[`POST /api/rest/2.0/searchdata`] to search data from a given data source. +* xref:#_fetch_liveboard_data_api[`POST /api/rest/2.0/metadata/liveboard/data`] to get data from a Liveboard. +* xref:#_fetch_answer_data_api[`POST /api/rest/2.0/metadata/answer/data`] to get data from a saved Answer. + +If Role-Based Access Control (RBAC) is enabled, the `DATADOWNLOADING` (Can download Data) privilege is required to use these APIs. Alternatively, if the granular data download RBAC privileges are enabled for your ThoughtSpot instance, the `CAN_DOWNLOAD_DETAILED_DATA` (Can download detailed data) is required. + +[NOTE] +To download a Liveboard or Answer as a PDF, PNG, CSV, or XLSX file instead of retrieving its data as JSON, see xref:report-apis-v2.adoc[Report APIs]. + +== Search data API + +The `/api/rest/2.0/searchdata` endpoint requires you to specify the data source object ID and a query string for a successful API call. You can also define additional parameters such as `runtime_filter`, `runtime_sort`, and `runtime_param_override` to apply runtime overrides on the data set. + +=== Data source +To search data via API call, you require at least view access to the data source object. The data source object can be a Model, View, or Table. + +You can specify the data source object GUID in the `logical_table_identifier`. The search data endpoint doesn't support searching data from multiple Models, Views, or Tables in a single API request. + +To find the GUID of the Model, View, or Table, use one of the following methods: + +Get data object GUID via API:: + +Send an API request to the `/api/rest/2.0/metadata/search` endpoint with the following parameters in the metadata array: + + ++ +.**Example** +[source,JSON] +---- + "metadata": [ + { + "identifier": "my_model", + "type": "LOGICAL_TABLE" + } + ] +---- + ++ +If you don't know the exact name of the data source object, specify the metadata `type` as `LOGICAL_TABLE` in your API request, and then copy the GUID of the data object from the API response. + +Find the GUID of the data object via UI:: +. Log in to your ThoughtSpot application instance: +. Navigate to **Data workspace**. ++ +---- +https:///#/data/tables/ +---- ++ +. On the **Data workspace** > **Data objects** page, select the data object. For example, if the data source object is a Model, click **Models** and then open the Model. +. In the address bar of the web browser, note the GUID of the data source object. For example, in the following address string, the GUID is `9d93a6b8-ca3a-4146-a1a1-e908b71b963f`: ++ +---- +https:///#/data/tables/9d93a6b8-ca3a-4146-a1a1-e908b71b963f +---- + +. Copy the GUID. + +=== Search query + +include::{path}/search-query-string.adoc[] + +.**Example** +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/searchdata' \ + -H 'Authorization: Bearer {access-token} + -H 'Accept: application/json'\ + -H 'Content-Type: application/json' \ + --data-raw '{ + "query_string": "[sales][store]", + "logical_table_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", +}' +---- + +//// +=== Using tokens generated from Spotter APIs as raw data + +For every natural language query and follow-up question, Spotter APIs such as `/api/rest/2.0/ai/answer/create`, `/api/rest/2.0/ai/agent/converse/sse`, return tokens in the API response. You can use these tokens as raw data to generate an Answer from ThoughtSpot via search data API. + +==== Request example + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/searchdata' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "query_string": "by [city], [product], [item type] = [item type].'\''jackets'\'', [region] = [region].'\''west'\'', sort by sum [sales] descending", + "logical_table_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "data_format": "COMPACT", + "record_offset": 0, + "record_size": 10 +}' +---- + +==== API response + +If the API request is successful, ThoughtSpot returns the Answer data for the query string sent in the API request. +//// + +== Fetch Liveboard Data API +To get data from a Liveboard object and its visualizations via `POST /api/rest/2.0/metadata/liveboard/data` endpoint, your user account must have at least view access to the Liveboard specified in the API request. + +The API request body must include the name or GUID of the Liveboard to fetch data. To get specific visualizations from a given Liveboard, add the names or GUIDs of the visualizations in the `visualization_identifiers` array. + +=== Liveboard data request example +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/metadata/liveboard/data' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Accept: application/json'\ + -H 'Content-Type: application/json' \ + --data-raw '{ + "metadata_identifier": "d084c256-e284-4fc4-b80c-111cb606449a", + "data_format": "COMPACT", + "visualization_identifiers": [ + "a9655c18-9855-4a73-9e7b-ff4fb6da334b", + "bf4c9814-82c1-4ec4-b879-57eae2134cb4", + "8c46d2b6-94c7-4ba7-a628-6e74e297f973", + "f6ef5d1f-cddb-4547-8b66-af4d5f4da5ad" + ] +}' +---- + +[#transient-lb-content] +=== Liveboard data with unsaved changes + +include::{path}/transient-lb-content.adoc[] + +.**Sample browser fetch request** + +[source,TypeScript] +---- +const embedRef = useEmbedRef(); + const handleFilterChanged: MessageCallback = () => { + embedRef.current + .trigger(HostEvent.getExportRequestForCurrentPinboard) + .then((transientPinboardContent) => { + console.log(transientPinboardContent.data); + + const payload = { + metadata_identifier: "abc", + data_format: "COMPACT", + record_offset: 0, + record_size: 10, + transient_content: JSON.stringify(transientPinboardContent.data), + }; + + fetch( + `https://{ThoughtSpot-Host}/api/rest/2.0/metadata/liveboard/data`, + { + method: "POST", + headers: { + Authorization: + "Bearer xxx", + Accept: "application/json", + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + } + ) + .then((response) => response.json()) + .then(console.log) + .catch(console.log); + }); + }; + + return ( + + ); +---- + +See also, link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_getexportrequestforcurrentpinboard[HostEvent.getExportRequestForCurrentPinboard]. + +To download a Liveboard with unsaved changes as a file, see xref:report-apis-v2.adoc#transient-lb-content-report[Liveboard data with unsaved changes] in the Report APIs documentation. + + +== Fetch Answer Data API + +To get data from a saved Answer object via `/api/rest/2.0/metadata/answer/data`, you need at least view access to the saved Answer. + +The API request body must include the name or GUID of the saved Answer. + +=== Answer data request example +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/metadata/answer/data' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Accept: application/json'\ + -H 'Content-Type: application/json' \ + --data-raw '{ + "metadata_identifier": "f605dbc7-db19-450b-8613-307118f74c3c", +}' +---- + +[#pagination] +== Pagination settings for Data APIs + +When you make REST API calls to some v2 Data endpoints to query data, the API may return many rows of data in response. By default, the following parameters are set in API requests to the v2 Data API endpoints: + +[source,JSON] +---- +{ + "data_format": "COMPACT", + "record_offset": 0, + "record_size": 10 +} +---- + +[WARNING] +==== +Do not set `record_size` to `-1`. On ThoughtSpot instances with a large number of objects or users, this can lead to slow responses, excessive logging, and out-of-memory failures. Specify an explicit `record_size` and iterate through pages programmatically. +==== + +The APIs return a maximum of 100000 rows of data at any given time. If you must retrieve a higher number of rows in an API call, contact ThoughtSpot Customer Support to increase the row size limit. However, if the record size and number of rows are high, the API may take a while to fetch the data, and the request may time out. + +== Runtime overrides +The Data API endpoints and the xref:report-apis-v2.adoc[Report API endpoints] support the following runtime overrides: + +* Runtime filters +* Runtime sorting of columns +* Runtime Parameters + +=== Runtime filters +To add runtime filters, in the `runtime_filter` property, add the `col1`, `op1`, and `val1` parameters JSON key-value format: + +[source,JSON] +---- +"runtime_filter": { + "col1": "type", + "op1": "EQ", + "val1": "roasted", +} +---- + +To add additional filters, increment the number at the end of each parameter for each filter: for example, col2, op2, val2, and so on. + +[source,JSON] +---- +"runtime_filter": { + "col1": "type", + "op1": "EQ", + "val1": "roasted", + "col2": "tea", + "op2": "EQ", + "val2": "barley" +} +---- + +Some operators such as allow more than one value in the `val` parameter: + +[source,JSON] +---- + "runtime_filter": { + "col1": "tea", + "op1": "CONTAINS", + "val1": [ + "barley", + "mint" + ], + "col2": "type", + "op2": "CONTAINS", + "val2": [ + "roasted", + "loose leaves" + ] +} +---- + +For more information, see xref:runtime-filters.adoc#rtOperator[Supported runtime filter operators] and xref:runtime-filters.adoc#_rest_api_v2_0_endpoints[Apply runtime filters via REST APIs]. + +=== Runtime parameters + +To add runtime Parameters, in the `runtime_param_override` property, add the `param1, and `paramVal1` parameters JSON key-value format. The Parameter value must be defined as per the data type. For example, `Date Param` and `Date List Param` Parameters, specify Epoch time as value. + +To apply Parameter overrides on Liveboards and Answers, ensure that the Parameters are configured in the Model used for generating Liveboard visualizations and Answer. + +[source,JSON] +---- + "runtime_param_override": { + "param1": "Double List Param", + "paramVal1": 0.5 + } +---- + +To add additional Parameter overrides, increment the number at the end of each parameter: for example, paramVal2, and so on. + +[source,JSON] +---- + "runtime_param_override": { + "param1": "Double List Param", + "paramVal1": 0.5, + "param2": "Date Param", + "paramVal2": 1696932000 + } +---- + +For more information, see xref:runtime-parameters.adoc[Runtime Parameter overrides]. + +=== Runtime sort + +To sort columns on a Liveboard or Answer, define runtime sort properties in `runtime_sort` as a key-value pair in JSON format. The `runtime_sort` object allows `sortCol1` and `asc1` properties. To sort more columns, increment the number at the end of the parameter for each key: for example, `sortCol2`, `asc2`, `sortCol3`, `asc3`, and so on. + + +[source,JSON] +---- + "runtime_sort": { + "sortCol1": "sales", + "asc1": true, + "sortCol2": "region", + "asc2": false + } +---- + +For more information, see xref:runtime-sort.adoc#_rest_api_v2_0[Runtime sorting of columns]. diff --git a/modules/ROOT/pages/data-report-v2-api.adoc b/modules/ROOT/pages/data-report-v2-api.adoc deleted file mode 100644 index a73d16087..000000000 --- a/modules/ROOT/pages/data-report-v2-api.adoc +++ /dev/null @@ -1,690 +0,0 @@ -= Data and Report APIs -:toc: true -:toclevels: 3 - -:page-title: data-apis -:page-pageid: fetch-data-and-report-apis -:page-description: Data and Report APIs - -== Data APIs -ThoughtSpot provides the following REST API v2 endpoints to fetch data: - -* xref:#_search_data_api[`POST /api/rest/2.0/searchdata`] to search data from a given data source. -* xref:#_fetch_liveboard_api[`POST /api/rest/2.0/metadata/liveboard/data`] to get data from a Liveboard. -* xref:#_fetch_answer_data_api[`POST /api/rest/2.0/metadata/answer/data`] to get data from a saved Answer. - -If Role-Based Access Control (RBAC) is enabled, the `DATADOWNLOADING` (Can download Data) privilege is required to use these APIs. Alternatively, if the granular data download RBAC privileges are enabled for your ThoughtSpot instance, the `CAN_DOWNLOAD_DETAILED_DATA` (Can download detailed data) is required. - -=== Search data API - -The `/api/rest/2.0/searchdata` endpoint requires you to specify the data source object ID and a query string for a successful API call. You can also define additional parameters such as `runtime_filter`, `runtime_sort`, and `runtime_param_override` to apply runtime overrides on the data set. - -==== Data source -To search data via API call, you require at least view access to the data source object. The data source object can be a Model, View, or Table. - -You can specify the data source object GUID in the `logical_table_identifier`. The search data endpoint doesn't support searching data from multiple Models, Views, or Tables in a single API request. - -To find the GUID of the Model, View, or Table, use one of the following methods: - -Get data object GUID via API:: - -Send an API request to the `/api/rest/2.0/metadata/search` endpoint with the following parameters in the metadata array: + - -+ -.**Example** -[source,JSON] ----- - "metadata": [ - { - "identifier": "my_model", - "type": "LOGICAL_TABLE" - } - ] ----- - -+ -If you don't know the exact name of the data source object, specify the metadata `type` as `LOGICAL_TABLE` in your API request, and then copy the GUID of the data object from the API response. - -Find the GUID of the data object via UI:: -. Log in to your ThoughtSpot application instance: -. Navigate to **Data workspace**. -+ ----- -https:///#/data/tables/ ----- -+ -. On the **Data workspace** > **Data objects** page, select the data object. For example, if the data source object is a Model, click **Models** and then open the Model. -. In the address bar of the web browser, note the GUID of the data source object. For example, in the following address string, the GUID is `9d93a6b8-ca3a-4146-a1a1-e908b71b963f`: -+ ----- -https:///#/data/tables/9d93a6b8-ca3a-4146-a1a1-e908b71b963f ----- - -. Copy the GUID. - -==== Search query - -include::{path}/search-query-string.adoc[] - -.**Example** -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/searchdata' \ - -H 'Authorization: Bearer {access-token} - -H 'Accept: application/json'\ - -H 'Content-Type: application/json' \ - --data-raw '{ - "query_string": "[sales][store]", - "logical_table_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", -}' ----- - -//// -==== Using tokens generated from Spotter APIs as raw data - -For every natural language query and follow-up question, Spotter APIs such as `/api/rest/2.0/ai/answer/create`, `/api/rest/2.0/ai/agent/converse/sse`, return tokens in the API response. You can use these tokens as raw data to generate an Answer from ThoughtSpot via search data API. - -===== Request example - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/searchdata' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "query_string": "by [city], [product], [item type] = [item type].'\''jackets'\'', [region] = [region].'\''west'\'', sort by sum [sales] descending", - "logical_table_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", - "data_format": "COMPACT", - "record_offset": 0, - "record_size": 10 -}' ----- - -===== API response - -If the API request is successful, ThoughtSpot returns the Answer data for the query string sent in the API request. -//// - -=== Fetch Liveboard Data API -To get data from a Liveboard object and its visualizations via `POST /api/rest/2.0/metadata/liveboard/data` endpoint, your user account must have at least view access to the Liveboard specified in the API request. - -The API request body must include the name or GUID of the Liveboard to fetch data. To get specific visualizations from a given Liveboard, add the names or GUIDs of the visualizations in the `visualization_identifiers` array. - -==== Example -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/metadata/liveboard/data' \ - -H 'Authorization: Bearer {access-token}'\ - -H 'Accept: application/json'\ - -H 'Content-Type: application/json' \ - --data-raw '{ - "metadata_identifier": "d084c256-e284-4fc4-b80c-111cb606449a", - "data_format": "COMPACT", - "visualization_identifiers": [ - "a9655c18-9855-4a73-9e7b-ff4fb6da334b", - "bf4c9814-82c1-4ec4-b879-57eae2134cb4", - "8c46d2b6-94c7-4ba7-a628-6e74e297f973", - "f6ef5d1f-cddb-4547-8b66-af4d5f4da5ad" - ] -}' ----- - -[#transient-lb-content] -==== Liveboard data with unsaved changes - -include::{path}/transient-lb-content.adoc[] - -.**Sample browser fetch request** - -[source,TypeScript] ----- -const embedRef = useEmbedRef(); - const handleFilterChanged: MessageCallback = () => { - embedRef.current - .trigger(HostEvent.getExportRequestForCurrentPinboard) - .then((transientPinboardContent) => { - console.log(transientPinboardContent.data); - - const payload = { - metadata_identifier: "abc", - data_format: "COMPACT", - record_offset: 0, - record_size: 10, - transient_content: JSON.stringify(transientPinboardContent.data), - }; - - fetch( - `https://{ThoughtSpot-Host}/api/rest/2.0/metadata/liveboard/data`, - { - method: "POST", - headers: { - Authorization: - "Bearer xxx", - Accept: "application/json", - "Content-Type": "application/json", - }, - body: JSON.stringify(payload), - } - ) - .then((response) => response.json()) - .then(console.log) - .catch(console.log); - }); - }; - - return ( - - ); ----- - -See also, link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_getexportrequestforcurrentpinboard[HostEvent.getExportRequestForCurrentPinboard]. - - -=== Fetch Answer Data API - -To get data from a saved Answer object via `/api/rest/2.0/metadata/answer/data`, you need at least view access to the saved Answer. - -The API request body must include the name or GUID of the saved Answer. - -==== Example -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/metadata/answer/data' \ - -H 'Authorization: Bearer {access-token}'\ - -H 'Accept: application/json'\ - -H 'Content-Type: application/json' \ - --data-raw '{ - "metadata_identifier": "f605dbc7-db19-450b-8613-307118f74c3c", -}' ----- - - -== Report APIs - -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, 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. - -=== Liveboard Report API - -To download a Liveboard report via `/api/rest/2.0/report/liveboard` API, you need at least view access to the Liveboard specified in the API request. - -In the `POST` request body, specify the GUID or name of the Liveboard as `metadata_identifier`. To download reports with specific visualizations, add GUIDs or names of the visualizations in the `visualization_identifiers`. - -To download visualizations from a specific Liveboard tab, specify the name or GUID of the tab in the `tab_identifiers` parameter. - -To download a personalized view of the Liveboard, specify the view name in the `personalised_view_identifier` attribute. - -[IMPORTANT] -==== -* The downloadable file returned in API response file is extensionless. You need to rename the downloaded file by typing in the relevant extension. -* If the Liveboard includes Note tiles, ensure that you do not pass the GUID of Note tiles as `visualization_identifiers` in the API request. Attempting to do so will lead to an error, and the API will return 400 error code in response. -* Attempting to override existing filter values with runtime filters while exporting a Liveboard will result in an error. -* If Role-Based Access Control (RBAC) is enabled, `DATADOWNLOADING` (Can download Data) privilege is required for Liveboard exports. -* If the granular Role-Based Access Control (RBAC) is enabled, the `CAN_DOWNLOAD_DETAILED_DATA` (Can download detailed data) privilege is required to export in the XLSX or CSV formats, and the `CAN_DOWNLOAD_VISUALS` (Can download visuals) privilege is required for PDF or PNG exports. In this case the `DATADOWNLOADING` privilege ceases to exist. -==== - -==== File Formats - -The default `file_format` is *CSV*. - -[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, - -* 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, - -* 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. -* New pivot tables generated in .xlsx workbooks using this API endpoint retain their complete visual formatting and structural integrity. - -===== 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. - -You can now also download continuous pdfs which matches the full length of your Liveboard, without breaking them into multiple A4 pages. - -* `page_size = CONTINUOUS` Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. -+ -When `page_size = CONTINUOUS`, the `include_filter_page` option works to show/hide the filter section in the PDF page (in a continuous PDF, there is no separate filter page, but the filters are included on the same page at the top). -* `zoom_level` offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. This can be set only when `page_size = CONTINUOUS`. Valid values are integers in the range of 45 and 175. - - -===== Sample API payload for PDF downloads - -[source,cURL] ----- -curl -X POST 'https://{ThoughtSpot-Host}/api/rest/2.0/report/liveboard' \ ---header 'Authorization: Bearer {access-token}' \ ---header '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": { - "page_size": "CONTINUOUS", - "zoom_level": 105, - "include_cover_page": true, - "include_custom_logo": true, - "include_filter_page": true, - "include_page_number": true, - "page_orientation": "PORTRAIT", - "truncate_table": false, - "page_footer_text": "Sample footer text" - } -}' ----- - -For *PNG* downloads, you can now define - -* `image_resolution` -* `image_scale` -* `include_header` - -[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`. -** 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*. - -==== - -===== Sample API payload for PNG 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": "PNG", - "tab_identifiers": [ - "bc6d6fb8-1e06-4617-b02f-51745e6933a6" - ], - "png_options": { - "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. - -[source,JSON] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/liveboard' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {access-token}' \ - --data-raw '{ - "metadata_identifier": "9bd202f5-d431-44bf-9a07-b4f7be372125", - "file_format": "PNG", - "override_filters": [ - { - "column_name": "Color", - "generic_filter": { - "op": "IN", - "values": [ - "almond", - "turquoise" - ] - }, - "negate": false - }, - { - "column_name": "Commit Date", - "date_filter": { - "datePeriod": "HOUR", - "number": 3, - "type": "LAST_N_PERIOD", - "op": "EQ" - } - }, - { - "column_name": "Sales", - "generic_filter": { - "op": "BW_INC", - "values": [ - "100000", - "70000" - ] - }, - "negate": true - } - ], - "png_options": { - "include_cover_page": true, - "include_filter_page": true - } -}' ----- - -[#transient-lb-content] -==== Liveboard data with unsaved changes - -include::{path}/transient-lb-content.adoc[] - -===== Sample browser fetch request - -[source,JavaScript] ----- -< iframe src = "http://ts_host:port/" id = "ts-embed" > < /iframe> -< script src = "/path/to/liveboard.js" > < /script> -< script > - const embed = new LiveboardEmbed("#embed", { - frameParams: {}, - }); - async function liveboardData() { - const transientPinboardContent = await embed.trigger(HostEvent.getExportRequestForCurrentPinboard); - const liveboardDataResponse = await fetch("https://ts_host:port/api/rest/2.0/report/liveboard", { - method: "POST", - body: createFormDataObjectWith({ - "transient_content": transientPinboardContent, - }), - }); - } -< /script> ----- - -See also, link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_getexportrequestforcurrentpinboard[HostEvent.getExportRequestForCurrentPinboard]. - -=== Answer Report API - -To download Answer data via `/api/rest/2.0/report/answer` API, you need at least view access to the saved Answer. - -In the request body, specify the GUID or name of the Answer object as `metadata_identifier`. - -The API supports exporting saved Answers, pinned Answers from a Liveboard, and Spotter-generated Answers. You can download Answer data in `CSV`, `XLSX`, `PNG`, and `PDF` format. The default `file_format` is `CSV`. - -[IMPORTANT] -==== -* If Role-Based Access Control (RBAC) is enabled, `DATADOWNLOADING` (Can download Data) privilege is required for Answer exports. -* If the granular Role-Based Access Control (RBAC) is enabled, the `CAN_DOWNLOAD_DETAILED_DATA` (Can download detailed data) privilege is required to export in the PDF, XLSX or CSV formats, and the `CAN_DOWNLOAD_VISUALS` (Can download visuals) privilege is required for PNG exports. In this case the `DATADOWNLOADING` privilege ceases to exist. -==== - -==== Example - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/answer' \ - -H 'Authorization: Bearer {access-token}'\ - -H 'Content-Type: application/json' \ - --data-raw '{ - "metadata_identifier": "9bd202f5-d431-44bf-9a07-b4f7be372125", - "file_format": "PNG" -}' ----- - -[NOTE] -==== -* Exported files are automatically named after the Answer title, with the file extension appended based on the selected format. -* HTML rendering is not supported for PDF exports of Answers with tables. -==== - - -Contact ThoughtSpot support to enable these enhanced settings for this API endpoint on your ThoughtSpot instance: - -* `personalised_view_identifier` [earlyAccess eaBackground]#Early Access# + -Optional parameter to specify the GUID of the personalised view of the `PINNED` Answer object that you want to download. -* `type` [earlyAccess eaBackground]#Early Access# + -Used to distinguish between a saved answer and a pinned answer on a Liveboard. Setting this parameter to `PINNED` allows the API to -accept the guid of a pinned Answer directly as the `metadata_identifier`. When -exporting an Answer, all Liveboard-level filters, Runtime Filters, and Column -Security Rules (CSR) are automatically applied to the export output. - -The `png_options` [earlyAccess eaBackground]#Early Access# support the following properties: - -[cols="1,1,3"] -|=== -|Property |Type |Description - -|`x_resolution` -|Number -|Width of the exported PNG in pixels. + -Valid range: `600px` to `3840px`. - -|`y_resolution` -|Number -|Height of the exported PNG in pixels. + -Valid range: `600px` to `3840px`. - -|`scaling` -|Integer -|Display scale percentage for objects rendered in the image. Adjusts the relative -size of visual elements without cropping the image. + -Valid range: `80%` to `500%`. -|=== - -You can now export the PNG of any Answer in any aspect ratio and any scaling or zoom level. Just configure, scale, and export exactly what you need. - -[#exportSpotterData] -==== Export data generated from Spotter APIs -To export results generated from Spotter APIs such as `/api/rest/2.0/ai/answer/create`, `/api/rest/2.0/ai/agent/converse/sse`, and `/api/rest/2.0/ai/conversation/{conversation_identifier}/converse`, include the session ID and generation number in the `POST` request body. - -When downloading a Spotter-generated Answer, do not specify the metadata object ID, because you will be exporting the data generated from a conversation session with Spotter and not a saved Answer. - -===== Request example - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/answer' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "file_format": "CSV", - "session_identifier": "ee077665-08e1-4a9d-bfdf-7b2fe0ca5c79", - "generation_number": 2 -}' ----- - -* `session_identifier` refers to session ID returned in the Spotter API response. -* `generation_number` indicates the Answer generation number. -* `file_format` specifies the format of the output. You can export the Spotter-generated data as PNG, CSV, XLSX, or PDF file. By default, the API exports this data in PNG file format. - -===== API Response - -If the API request is successful, ThoughtSpot returns the data in the specified file format. You can download the file to use it later or import it into your application environment. - -//// -===== Response codes -[width="100%" cols="2,4"] -[options='header'] -|=== -|HTTP status code|Description -|**200**| Successful operation -|**400**| Invalid parameter -|**401**| Unauthorized access -|**401**| Forbidden request -|**500**| Internal error -|=== -//// - -== Pagination settings for Data APIs - -When you make REST API calls to some v2 Data endpoints to query data, the API may return many rows of data in response. By default, the following parameters are set in API requests to the v2 Data API endpoints: - -[source,JSON] ----- -{ - "data_format": "COMPACT", - "record_offset": 0, - "record_size": 10 -} ----- - -[WARNING] -==== -Do not set `record_size` to `-1`. On ThoughtSpot instances with a large number of objects or users, this can lead to slow responses, excessive logging, and out-of-memory failures. Specify an explicit `record_size` and iterate through pages programmatically. -==== - -The APIs return a maximum of 100000 rows of data at any given time. If you must retrieve a higher number of rows in an API call, contact ThoughtSpot Customer Support to increase the row size limit. However, if the record size and number of rows are high, the API may take a while to fetch the data, and the request may time out. - -== Runtime overrides -The Data API endpoints support the following runtime overrides: - -* Runtime filters -* Runtime sorting of columns -* Runtime Parameters - -=== Runtime filters -To add runtime filters, in the `runtime_filter` property, add the `col1`, `op1`, and `val1` parameters JSON key-value format: - -[source,JSON] ----- -"runtime_filter": { - "col1": "type", - "op1": "EQ", - "val1": "roasted", -} ----- - -To add additional filters, increment the number at the end of each parameter for each filter: for example, col2, op2, val2, and so on. - -[source,JSON] ----- -"runtime_filter": { - "col1": "type", - "op1": "EQ", - "val1": "roasted", - "col2": "tea", - "op2": "EQ", - "val2": "barley" -} ----- - -Some operators such as allow more than one value in the `val` parameter: - -[source,JSON] ----- - "runtime_filter": { - "col1": "tea", - "op1": "CONTAINS", - "val1": [ - "barley", - "mint" - ], - "col2": "type", - "op2": "CONTAINS", - "val2": [ - "roasted", - "loose leaves" - ] -} ----- - -For more information, see xref:runtime-filters.adoc#rtOperator[Supported runtime filter operators] and xref:runtime-filters.adoc#_rest_api_v2_0_endpoints[Apply runtime filters via REST APIs]. - -=== Runtime parameters - -To add runtime Parameters, in the `runtime_param_override` property, add the `param1, and `paramVal1` parameters JSON key-value format. The Parameter value must be defined as per the data type. For example, `Date Param` and `Date List Param` Parameters, specify Epoch time as value. - -To apply Parameter overrides on Liveboards and Answers, ensure that the Parameters are configured in the Model used for generating Liveboard visualizations and Answer. - -[source,JSON] ----- - "runtime_param_override": { - "param1": "Double List Param", - "paramVal1": 0.5 - } ----- - -To add additional Parameter overrides, increment the number at the end of each parameter: for example, paramVal2, and so on. - -[source,JSON] ----- - "runtime_param_override": { - "param1": "Double List Param", - "paramVal1": 0.5, - "param2": "Date Param", - "paramVal2": 1696932000 - } ----- - -For more information, see xref:runtime-parameters.adoc[Runtime Parameter overrides]. - -=== Runtime sort - -To sort columns on a Liveboard or Answer, define runtime sort properties in `runtime_sort` as a key-value pair in JSON format. The `runtime_sort` object allows `sortCol1` and `asc1` properties. To sort more columns, increment the number at the end of the parameter for each key: for example, `sortCol2`, `asc2`, `sortCol3`, `asc3`, and so on. - - -[source,JSON] ----- - "runtime_sort": { - "sortCol1": "sales", - "asc1": true, - "sortCol2": "region", - "asc2": false - } ----- - -For more information, see xref:runtime-sort.adoc#_rest_api_v2_0[Runtime sorting of columns]. - - diff --git a/modules/ROOT/pages/database-api.adoc b/modules/ROOT/pages/database-api.adoc index 142474225..6ba437fbb 100644 --- a/modules/ROOT/pages/database-api.adoc +++ b/modules/ROOT/pages/database-api.adoc @@ -1,11 +1,13 @@ -= Database API += REST API v1 - Database API endpoints :toc: true :toclevels: 1 :page-title: Database API -:page-pageid: database-api +:page-pageid: database-api-v1 :page-description: Use the database REST API endpoints to fetch table, schema, and database details, and create tables and run TQL commands +include::{path}/rest-apiv1-deprecation-note.adoc[] + The Database API endpoints allow you to get details of your databases and their schemas, create tables within a database, and run TQL commands in Falcon-based ThoughtSpot deployments. To modify the schema of a database or add a new table to a database, you must have admin access to the database and its objects. diff --git a/modules/ROOT/pages/dependency-apis.adoc b/modules/ROOT/pages/dependency-apis.adoc index 33a75f78d..a852b2ea9 100644 --- a/modules/ROOT/pages/dependency-apis.adoc +++ b/modules/ROOT/pages/dependency-apis.adoc @@ -1,11 +1,13 @@ -= Dependent objects APIs += REST API v1 - Dependent object API endpoints :toc: true :toclevels: 1 :page-title: Get details of dependent objects -:page-pageid: dependent-objects-api +:page-pageid: dependent-objects-api-v1 :page-description: The dependency API endpoints allow you to get details of the dependents for a metadata object +include::{path}/rest-apiv1-deprecation-note.adoc[] + The `tspublic/v1/dependency` endpoints allow you to query dependent objects for a metadata object type or ID. Dependency in ThoughtSpot is defined as a relation between the referenced and referencing objects. If the referenced object cannot be deleted without first deleting the referencing object, the referenced object is considered as a dependent object. diff --git a/modules/ROOT/pages/deploy-with-tml-apis.adoc b/modules/ROOT/pages/deploy-with-tml-apis.adoc index 2425adcf9..48ec1e6da 100644 --- a/modules/ROOT/pages/deploy-with-tml-apis.adoc +++ b/modules/ROOT/pages/deploy-with-tml-apis.adoc @@ -255,7 +255,7 @@ if 'edoc' in yaml_tml[0]: [#linkImportRelease] == TML Import with obj_id and variables -The xref:tml-api.adoc#import[/metadata/tml/import] REST API endpoint is used to upload any number of TML files at one time. +The xref:tml-import.adoc#import-tml[/metadata/tml/import] REST API endpoint is used to upload any number of TML files at one time. All details of the objects to be created or modified are specified *within the uploaded TML file*, matching first on `obj_id` and then on `guid` if `obj_id` is not present. diff --git a/modules/ROOT/pages/deprecated-features.adoc b/modules/ROOT/pages/deprecated-features.adoc index d90d833e3..a6f33608b 100644 --- a/modules/ROOT/pages/deprecated-features.adoc +++ b/modules/ROOT/pages/deprecated-features.adoc @@ -14,7 +14,7 @@ As ThoughtSpot applications evolve, some existing features will be deprecated an [options='header'] |===== |Feature|Impacted interface and release versions|Deprecation date |End of Support / removal from the product -a|xref:deprecated-features.adoc#liveboardAnswerDiscoverable[Liveboard and answer discoverability] +a|xref:deprecated-features.adoc#liveboardDiscoverable[Liveboard and answer discoverability] a|ThoughtSpot Cloud 26.2.0.cl and later | February 2026 | August 2026 a|xref:deprecated-features.adoc#everynmins[Minute-level schedule frequency] |ThoughtSpot Cloud 26.8.0.cl and later | August 2026 | - @@ -147,7 +147,7 @@ Impact on your instance:: * For new users, API calls to the `POST /api/rest/2.0/report/liveboard` endpoint for PNG exports with `include_cover_page` and `include_filter_page` will result in an error. Use the new PNG export options. //If you still have to use these options for your ThoughtSpot instance contact ThoughtSpot support to revert to these legacy settings. -For more information on PNG export, see xref:data-report-v2-api.adoc#_liveboard_report_api[Liveboard Report API]. +For more information on PNG export, see xref:report-apis-v2.adoc#_liveboard_report_api[Liveboard Report API]. Recommended action:: * We recommend transitioning to the new flow for PNG exports, as the `include_cover_page` and `include_filter_page` attributes will be removed in a future release. diff --git a/modules/ROOT/pages/developer-playground.adoc b/modules/ROOT/pages/developer-playground.adoc index a4525ba0c..efa69e263 100644 --- a/modules/ROOT/pages/developer-playground.adoc +++ b/modules/ROOT/pages/developer-playground.adoc @@ -11,7 +11,7 @@ The *Playground* allows developers to try Visual Embed APIs, play with the code, You can explore the following SDK components in the Playground. * xref:developer-playground.adoc#playground-search[Search] -* xref:developer-playground.adoc#playground-nls-search[Natural Language Search] +//* xref:developer-playground.adoc#playground-nls-search[Natural Language Search] * xref:developer-playground.adoc#playground-spotter[Spotter] * xref:developer-playground.adoc#playground-liveboard[Liveboards] * xref:developer-playground.adoc#playground-visualization[Visualizations] @@ -129,6 +129,7 @@ Hides the charts and tables that appear beneath the search bar by default. For e ++++ //// +//// [#playground-nls-search] == Natural Language Search @@ -186,6 +187,7 @@ Shows the code for interface customization. You can define custom styles and def For more information about CSS variables, styles, and customizations options, see xref:css-customization.adoc[Customize CSS]. | |==== +//// [#playground-spotter] == Spotter @@ -510,7 +512,7 @@ After SpotterCode updates the code editor: For more information about the configuration settings and parameters, see the following pages: * xref:SearchViewConfig.adoc[SearchViewConfig] -* xref:SageViewConfig.adoc[SageViewConfig] +//* xref:SageViewConfig.adoc[SageViewConfig] * xref:SpotterAgentEmbedViewConfig.adoc[SpotterAgentEmbedViewConfig] * xref:LiveboardViewConfig[LiveboardViewConfig] * xref:AppViewConfig.adoc[AppViewConfig] @@ -518,7 +520,7 @@ For more information about the configuration settings and parameters, see the fo See the following pages for information on how to embed a ThoughtSpot component: * xref:embed-search.adoc[Embed ThoughtSpot Search] -* xref:embed-nls.adoc[Embed Natural Language Search] +//* xref:embed-nls.adoc[Embed Natural Language Search] * xref:embed-spotter.adoc[Embed Spotter] * xref:embed-a-viz.adoc[Embed a visualization] * xref:embed-pinboard.adoc[Embed a Liveboard] diff --git a/modules/ROOT/pages/embed-ai-analytics.adoc b/modules/ROOT/pages/embed-ai-analytics.adoc index 6d52bf60b..772b8e030 100644 --- a/modules/ROOT/pages/embed-ai-analytics.adoc +++ b/modules/ROOT/pages/embed-ai-analytics.adoc @@ -1,8 +1,8 @@ -= Embed AI Search and Analytics += Embed Spotter AI analytics :toc: true :toclevels: 3 -:page-title: Embed AI Search and Analytics +:page-title: Embed Spotter AI and Analytics :page-pageid: embed-ai-search-analytics :page-description: To embed the ThoughtSpot Spotter and conversational analytics experience in your app, you can use the `SpotterEmbed` or `SpotterAgentEmbed` SDK components. @@ -62,13 +62,15 @@ You can use this version if your ThoughtSpot embedded app needs only metadata-le |==== == SDK libraries for embedding Spotter -ThoughtSpot provides the following Visual Embed SDK libraries for embedding Spotter capabilities in your app: +ThoughtSpot provides the xref:embed-spotter.adoc[`SpotterEmbed`] in the Visual Embed SDK to embed Spotter interface and its capabilities in your app. -* xref:embed-spotter.adoc[`SpotterEmbed`] + -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. +If you want to integrate just the Spotter AI analytics without ThoughtSpot's UI in your chatbot, consider using the xref:mcp-integration.adoc[Spotter MCP Server]. + +//// * xref:embed-spotter-agent.adoc[`SpotterAgentEmbed`] + 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 @@ -292,7 +294,117 @@ Action IDs to show or hide the MCP connector panel, connector resources section, * `Action.SpotterChatConnectorResources` * `Action.SpotterChatConnectors` * `Action.SpotterChatModeSwitcher` +|Stop answer generation + + +Allows users to interrupt an in-progress answer generation in the Spotter interface. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +**Feature status**: Available from SDK v1.48.0 and ThoughtSpot Cloud 26.5.0.cl. + + +**Required settings**: Spotter 2 or Spotter 3 must be enabled at the instance level. + + +**Embed SDK component**: Use `SpotterEmbed`. + + +**Default state in embed**: Disabled by default. To enable, set `enableStopAnswerGenerationEmbed` to `true` in the SDK. + +|File upload in Spotter chat + + +Enables users to upload files from their local directory to provide context for a Spotter query. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +**Feature status**: Available from SDK v1.49.0 and ThoughtSpot Cloud 26.6.0.cl. + + +**Required settings**: Spotter 3 must be enabled at the instance level. + + +**Embed SDK component**: Use `SpotterEmbed`. Also supported in `LiveboardEmbed` and `AppEmbed`. + + +**Default state in embed**: Disabled by default. To enable, set `spotterFileUploadEnabled` to `true` in the `spotterChatConfig` object. + +To restrict uploaded file types, use `spotterFileUploadFileTypes` within `spotterChatConfig`. + +|link:https://docs.thoughtspot.com/cloud/latest/spotter-starter-prompts[Spotter starter prompts, window=_blank] + + +Preconfigured search questions displayed as clickable suggestion pills in the Spotter chat interface. Supports three categories: Basic Search (`quick`), Deep Analysis (`research`), and Data Literacy (`previewData`). + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +**Feature status**: Basic enablement available from SDK v1.51.0 and ThoughtSpot Cloud 26.8.0.cl. Custom configuration with category keys available from SDK v1.52.0 and ThoughtSpot Cloud 26.9.0.cl. + + +**Required settings**: Spotter 3 must be enabled at the instance level. + + +**Embed SDK component**: Use `SpotterEmbed`. Also supported in `LiveboardEmbed` and `AppEmbed`. + + +**Default state in embed**: Disabled by default. To enable, set `enableStarterPrompts` to `true` or set `starterPrompts.enable` to `true` in the `spotterChatConfig` object. + + +To customize individual category labels and questions, use the `starterPrompts` object with `quick`, `research`, and `previewData` keys. Only the first 4 questions per category are rendered. + + +Use the following Action IDs to control the visibility of individual starter prompt pills: + +* `Action.QuickSearchPill` +* `Action.DeepAnalysisPill` +* `Action.DataLiteracyPill` + +|Share conversation + + +Allows users to share a Spotter conversation with other users or groups. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +**Feature status**: Available from SDK v1.52.0 and ThoughtSpot Cloud 26.9.0.cl. + + +**Required settings**: Spotter 3 must be enabled at the instance level. + + +**Embed SDK component**: Use `SpotterEmbed`. Also supported in `AppEmbed`. + + +**Default state in embed**: Disabled by default. To enable, set `enableShareConversation` to `true` in the `spotterShareConversationConfig` object. + +To open a shared conversation in read-only mode, set `sharedConversationId` with the conversation ID. + +|Default query mode + + +Sets the default query mode (Fast Search or Research) when Spotter loads. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +**Feature status**: Available from SDK v1.52.0 and ThoughtSpot Cloud 26.9.0.cl. + + +**Required settings**: Spotter 3 must be enabled at the instance level. + + +**Embed SDK component**: Use `SpotterEmbed` and `AppEmbed`. + + +**Default state in embed**: Defaults to `SpotterQueryMode.FAST_SEARCH`. To set the default to Research mode, set `defaultQueryMode` to `SpotterQueryMode.RESEARCH`. The setting applies per session and does not persist as a user preference. + +|Multiple data sources + + +Allows setting multiple data source GUIDs for Spotter to query. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +**Feature status**: Disabled by default. + +**Required settings** Spotter 3 must be enabled at the instance level. + + +**Embed SDK component**: Use `SpotterEmbed`. + +**Default state in embed**: Not enabled by default. To use, set the `dataSources` array with the list of data source GUIDs. When `dataSources` is provided, it takes precedence over `worksheetId`. || |==== diff --git a/modules/ROOT/pages/embed-event-error-best-practices.adoc b/modules/ROOT/pages/embed-event-error-best-practices.adoc index e9bdc49f0..36c89620e 100644 --- a/modules/ROOT/pages/embed-event-error-best-practices.adoc +++ b/modules/ROOT/pages/embed-event-error-best-practices.adoc @@ -6,6 +6,17 @@ :page-pageid: handling-embed-errors :page-description: This document lists the best practices for handling error events. + +[IMPORTANT] +==== +In the upcoming ThoughtSpot Cloud 26.10.0.cl and Visual Embed SDK 1.53.0 versions, `EmbedEvent.Error` will include a `severity` field that categorizes errors into three severity levels: `SEV1`, `SEV2`, and `SEV3`. + +ThoughtSpot recommends reviewing your error handing logic to prepare your integrations for this change. If your application currently handles all errors uniformly, you may need to update your error handling to distinguish between critical errors (SEV1) that require tearing down the embed and less severe errors (SEV2, SEV3) that can be logged or ignored. + +//For more information, see the xref:embed-event-error-best-practices.adoc#_error_severity_levels[Error severity levels] section. +==== + + The ThoughtSpot Visual Embed SDK provides a layered approach to error handling. `EmbedEvent.Error` is a real-time outbound event emitted from the embedded ThoughtSpot iframe to the host application, signaling that something has gone wrong, either inside the SDK itself, inside the embedded app (the iframe), or as a result of an invalid HostEvent payload sent by the host. @@ -198,6 +209,42 @@ LiveboardEmbed.on(EmbedEvent.Error, (error) => { ---- |=== +//// +[#_error_severity_levels] +== Error severity levels + +Starting from ThoughtSpot Cloud 26.10.0.cl (Visual Embed SDK 1.53.0), the `EmbedEvent.Error` payload includes a `severity` field that categorizes errors into three levels: + +[cols="1,2,3", options="header"] +|=== +| Severity | Description | Recommended handling + +| `SEV1` | The embed is down: the app crashed and a fallback page is showing. | Consider tearing down the embed and re-initializing, or showing a custom error message to the user. +| `SEV2` | An error was shown to the user; the embed still works. | Log the error for monitoring. No immediate action is required unless the error indicates a persistent issue. +| `SEV3` | Everything else, including validation of the embedder's own input. | Log the error for debugging. These errors are typically not user-facing and can often be ignored if the application is functioning correctly. +|=== + +The `severity` field is included in the error payload as an optional integer value: + +[source,json] +---- +{ + "type": "Error", + "data": { + "errorType": "API", + "error": { + "message": "..." + }, + "severity": 2 + } +} +---- + +[NOTE] +==== +The `severity` field is backward compatible. If your application does not use the `severity` field, the error handling behavior remains unchanged. +==== +//// == Payload shapes [source,typescript] diff --git a/modules/ROOT/pages/embed-nls.adoc b/modules/ROOT/pages/embed-nls.adoc deleted file mode 100644 index 15513f5c8..000000000 --- a/modules/ROOT/pages/embed-nls.adoc +++ /dev/null @@ -1,270 +0,0 @@ -= Embed Natural Language Search (legacy interface) -:toc: true -:toclevels: 2 - -:page-title: Embed Natural Language Search -:page-pageid: embed-nls -:page-description: You can use the SageEmbed SDK library to embed ThoughtSpot Natural Language Search experience in your application. - - -[IMPORTANT] -==== -The legacy Natural Language Search interface, also referred to as `Sage`, will be deprecated in July 2025. Customers who want to embed ThoughtSpot's natural language search interface are advised to upgrade to xref:embed-spotter.adoc[Spotter]. For more information, see the xref:deprecated-features.adoc#SageDeprecationNotice[deprecation notice]. -==== - -ThoughtSpot provides the `SageEmbed` SDK package to help developers embed Natural Language Search (legacy) experience, which supports the following features: - -* Ability to pass natural language queries as search text -* AI-generated sample Answers -* AI-suggested popular queries - -== Search components - -The `SageEmbed` package allows you embed the following Search components in your application: - -* Search bar that supports natural language queries + -+ -Unlike the token-based Search, the Search bar in the Natural Language Search interface allows you to type questions in the natural language format. Users can also select popular queries suggested by ThoughtSpot. + -* Worksheet selector + -Allows selecting a Worksheet as data source for search queries. The AI Answer Search must be enabled on the Worksheet for search queries to return AI-generated Answers. -* Sample questions + -The sample questions panel shows the AI-suggested search queries and Answers. To see AI generated answers, select an AI-enabled worksheet. -* Answer page + -The API generated Answer page shows chart or table and an **Edit** button to modify the search query. The Answer page also includes a feedback widget for users to send feedback. - -== Get started -Get started with embedding Natural Language Search and complete the steps described in the following sections - -=== Import the SageEmbed package - -Import the `SageEmbed` SDK library to your application environment: - -**npm** -[source,JavaScript] ----- -import { - SageEmbed, - AuthType, - init, - prefetch, - EmbedEvent, - HostEvent -} -from '@thoughtspot/visual-embed-sdk'; ----- - -**ES6** -[source,JavaScript] ----- - ---- -== Initialize the SDK +=== Initialize the SDK To initialize the SDK, the following information is required: @@ -77,17 +82,9 @@ const spotterAgentEmbed = new SpotterAgentEmbed(document.getElementById('ts-embe }); ---- - == Customization controls for the embed view (Optional) - -The embed package for Spotter includes the additional configuration flags to customize the Spotter Agent. Spotter Agent includes only the AI search experience with the Search bar by default. The interface design and styling is controlled by your host app. However, the SDK provides a few controls to customize search experience and app interactions. - -For more information, see the following pages: - -* xref:SpotterAgentEmbedViewConfig.adoc[SpotterAgentEmbedConfig] for embed view customization properties -* xref:Action.adoc[Action customization framework] to show or hide actions on the Answers generated from the query + -* Event handlers for xref:HostEvent.adoc[host] and xref:EmbedEvent.adoc[embed] app interaction -* xref:css-customization.adoc[Style customization framework] to customize style, text strings, and icons in the embedded view. +The SDK supports limited customization controls when you embed using the `SpotterAgentEmbed` component. +For information about the available interface customization settings, see xref:SpotterAgentEmbedViewConfig.adoc[SpotterAgentEmbedViewConfig]. == Render the embedded object @@ -115,8 +112,7 @@ const spotterAgentEmbed = new SpotterAgentEmbed('#ts-spotter-agent', { width: '100%', }, worksheetId: "your-worksheet-id", // ID of the data source object (Model) to query data - // Optionally, you can set other configuration options here - // Add event listeners + // Other config attributes }); spotterAgentEmbed.render(); @@ -129,7 +125,7 @@ If the embedding is successful, you'll see the Spotter search panel at the botto + [.widthAuto] [.bordered] -image::./images/spotterAgentEmbed.png[Spotter Agent embed] +image::./images/spotterAgentEmbed.png[SpotterAgentEmbed] * Type your query, click the *Send* button to prompt Spotter and generate a response. + @@ -138,7 +134,6 @@ image::./images/spotterAgentEmbed.png[Spotter Agent embed] image::./images/spotterAgentEmbedQuery.png[Spotter Agent embed query] == Additional resources -* link:https://developers.thoughtspot.com/docs/Class_SpotterAgentEmbed[SpotterAgentEmbed classes and methods] +* xref:SpotterAgentEmbed.adoc[SpotterAgentEmbed classes and methods] * xref:spotter-in-custom-chatbot.adoc[Integrate Spotter in your custom chatbot tutorial] * link:https://github.com/thoughtspot/developer-examples/tree/main/visual-embed/spotter/spotter-agent-embed[Developer examples, window=_blank] -* link:https://codesandbox.io/p/sandbox/youthful-paper-km4zh6?file=%2Fsrc%2FApp.js%3A51%2C47-51%2C62[Code sandbox, window=_blank] diff --git a/modules/ROOT/pages/embed-spotterViz.adoc b/modules/ROOT/pages/embed-spotterViz.adoc index 3b9cdc892..6f5566eeb 100644 --- a/modules/ROOT/pages/embed-spotterViz.adoc +++ b/modules/ROOT/pages/embed-spotterViz.adoc @@ -68,8 +68,8 @@ Use the following properties to replace default ThoughtSpot terminology in the S * `liveboardBrandName`. __String__. Replaces the term "Liveboard" in the agent's responses. For example, you can set this to `'Dashboard'` to have SpotterViz refer to generated views as dashboards. * `spotterBrandName`. __String__. Replaces the term "Spotter" in the agent's responses. Use this parameter to rebrand Spotter with your own product name. For example, `'AI Analyst'`. * `insightTileBrandName`. __String__. Replaces the term "Insight tile" in the UI and in the agent's responses. For example, `'Insight card'`. -* `insightTileViewPlanLabel`. __String__. Replaces the "View plan" label in the insight tile action menu. For example, `'Show details'`. Custom term used to replace "View plan" in the insight tile menu. -* `insightTileLoaderText`. __String__. Replaces the default loader text shown on an insight tile while it is generating content. For example,`'Generating insight...;'`. +* `insightTileViewPlanLabel`. __String__. Replaces the "View plan" label in the insight tile action menu. For example, `'Show details'`. +* `insightTileLoaderText`. __String__. Replaces the default loader text shown on an insight tile while it is generating content. For example, `'Generating insight...'`. === SpotterViz in Liveboard embedding [source,javascript] @@ -104,7 +104,6 @@ const embed = new LiveboardEmbed('#embed-container', { insightTileViewPlanLabel: 'Show details', insightTileLoaderText: 'Generating insight...', hideStarterPrompts: false, - hideStarterPrompts: false, customStarterPrompts: [ { id: '1', diff --git a/modules/ROOT/pages/embed-without-sdk.adoc b/modules/ROOT/pages/embed-without-sdk.adoc index 198d6f4c0..8b5e62609 100644 --- a/modules/ROOT/pages/embed-without-sdk.adoc +++ b/modules/ROOT/pages/embed-without-sdk.adoc @@ -325,7 +325,7 @@ image::./images/iframe-embed.png[iFrame embedding] For a complete list of feature flags and parameters, see the following pages: * xref:SearchViewConfig.adoc[SearchViewConfig] -* xref:SageViewConfig.adoc[SageViewConfig] +//* xref:SageViewConfig.adoc[SageViewConfig] * xref:LiveboardViewConfig.adoc[LiveboardViewConfig] * xref:AppViewConfig.adoc[AppViewConfig] diff --git a/modules/ROOT/pages/feature-matrix-license.adoc b/modules/ROOT/pages/feature-matrix-license.adoc index deac379e5..ca190f7bc 100644 --- a/modules/ROOT/pages/feature-matrix-license.adoc +++ b/modules/ROOT/pages/feature-matrix-license.adoc @@ -217,7 +217,7 @@ a|xref:metadata-api.adoc[Metadata] + __Query APIs only__ -a|xref:tml-api.adoc[TML] + +a|xref:tml.adoc[TML] + //// __Require `DATAMANAGEMENT` privilege__ diff --git a/modules/ROOT/pages/filters_overview.adoc b/modules/ROOT/pages/filters_overview.adoc index d4c0d9849..fe4672d0d 100644 --- a/modules/ROOT/pages/filters_overview.adoc +++ b/modules/ROOT/pages/filters_overview.adoc @@ -28,8 +28,10 @@ You can define xref:runtime-filters.adoc[runtime filters] and xref:runtime-param [NOTE] ==== * Runtime filters do not display as UI filter components. -* The SDK processes at most 49 entries per embed. Any objects at index 50 or -beyond are silently dropped without an error or warning. See +* Runtime filter limits vary by input path. URL-based runtime filters are capped at 50. +When using the Visual Embed SDK `runtimeFilters` property, the limit is configurable by a +ThoughtSpot administrator, with a default and maximum of 1,000 runtime filters. Filters beyond the enforced +limit are silently dropped without an error or warning. See xref:runtime-filters.adoc#_maximum_filter_count[Runtime filter limit] for more information. ==== diff --git a/modules/ROOT/pages/full-app-customize.adoc b/modules/ROOT/pages/full-app-customize.adoc index 158fce723..2ce50aea1 100644 --- a/modules/ROOT/pages/full-app-customize.adoc +++ b/modules/ROOT/pages/full-app-customize.adoc @@ -1,8 +1,8 @@ -= Customize the home page and navigation for full application embedding += Customize your full application embed :toc: true :toclevels: 3 -:page-title: Customize the home page and navigation for full application embedding +:page-title: Customize your full application embed :page-pageid: full-app-customize :page-description: Customize the home page and navigation for full application embedding @@ -16,7 +16,6 @@ ThoughtSpot supports the following experience modes in full application embeddin The classic V1 and V2 navigation and homepage experience modes are deprecated as of ThoughtSpot Cloud 26.8.0.cl. Starting from this release, all embedded sessions render in the V3 navigation experience by default. ==== - == UI experience modes ThoughtSpot supports V3 and V4 home page and navigation experiences for full application embedding. diff --git a/modules/ROOT/pages/getting-started.adoc b/modules/ROOT/pages/getting-started.adoc index 2a9165058..8be78539c 100644 --- a/modules/ROOT/pages/getting-started.adoc +++ b/modules/ROOT/pages/getting-started.adoc @@ -1,4 +1,4 @@ -= Embed ThoughtSpot += Embed with Visual Embed SDK :toc: true :linkattrs: :sectanchors: diff --git a/modules/ROOT/pages/group-api.adoc b/modules/ROOT/pages/group-api.adoc index b11493b81..13ca0b25a 100644 --- a/modules/ROOT/pages/group-api.adoc +++ b/modules/ROOT/pages/group-api.adoc @@ -1,22 +1,23 @@ -= Group APIs += REST API v1 - Group API endpoints :toc: true :toclevels: 1 :page-title: Group API -:page-pageid: group-api +:page-pageid: group-api-v1 :page-description: The group API endpoints allow you to define group privileges and user access to ThoughtSpot objects and data +include::{path}/rest-apiv1-deprecation-note.adoc[] + +== Supported operations The Group API endpoints allow you to programmatically create and manage user groups, configure privileges, and assign users to a group. +include::{path}/group-api-list.adoc[] + [#group-privilege] == User groups and privileges include::{path}/group-privileges.adoc[] -== Supported operations - -include::{path}/group-api-list.adoc[] - === Required permissions You must have administrator access to create, edit, or delete group objects, configure privileges, and assign users. diff --git a/modules/ROOT/pages/integration-overview.adoc b/modules/ROOT/pages/integration-overview.adoc deleted file mode 100644 index 244231639..000000000 --- a/modules/ROOT/pages/integration-overview.adoc +++ /dev/null @@ -1,71 +0,0 @@ -= Integration guidelines -:toc: true - -:page-title: ThoughtSpot Application Integration Guidelines -:page-pageid: integration-guidelines -:page-description: ThoughtSpot Embedded Analytics - -ThoughtSpot recommends that you browse through the following guidelines before embedding ThoughtSpot in your application. - -== Define application workflows - -The ThoughtSpot Visual Embed SDK includes a Javascript library to programmatically embed search, Liveboards, visualizations, and or the full ThoughtSpot experience. - -In addition to the Visual Embed SDK, ThoughtSpot provides REST APIs to query data from the ThoughtSpot application. For example, you can construct a search Answer using the data APIs and use this link to embed search answers with your application. - -Irrespective of the method you use for embedding, make sure you define your application workflows and authentication criteria to enable seamless navigation between the host and embedded interfaces. - -== Determine the hosting domain - -When you embed ThoughtSpot into your app, the application URL will be set as `.thoughtspot.cloud` by default. Most web browsers, including Safari and Firefox, block third-party cookies by default. To ensure that embedding works on browsers that don’t allow third-party cookies and cross-domain requests, you can customize the domain name of the embedded ThoughtSpot instance. For more information, see xref:custom-domain-configuration.adoc[Custom domain configuration]. - -[NOTE] -==== -If your deployment requires both ThoughtSpot standalone application and the embedded ThoughtSpot instance, we recommend that you host these instances on separate domains or non-overlapping sub-domains. -==== - -== Define user roles and privileges - -The ThoughtSpot application integration involves several workflows that require users to have specific privileges: - -ThoughtSpot admin:: -ThoughtSpot administrators who define the authentication workflow and create user groups. + -Access control in ThoughtSpot is managed through the users and groups that are stored locally on ThoughtSpot, even if the users are authenticated using SSO or Trusted Authentication. This means that to provide access to content or system privileges, admin users must create users and groups in ThoughtSpot. -+ -For more information, see link:https://docs.thoughtspot.com/cloud/latest/user-management[Managing users, window=_blank] and link:https://docs.thoughtspot.com/cloud/latest/group-management[Managing Groups, window=_blank]. - -Developer:: -Application developers with privileges to use the Developer portal and embed ThoughtSpot components in their host application. + -Developer users can also customize the look and feel of the UI, add custom actions to an embedded visualization or Liveboard, and modify security settings such as CORS and CSP. For more information, see xref:user-roles.adoc[Developer access]. - -== Define an authentication method - -For initial development and testing purposes, you can use the basic authentication method with xref:api-auth-session.adoc[session REST APIs] to manage ThoughtSpot user logins and sessions. However, ThoughtSpot recommends that you use the EmbeddedSSO or trusted authentication service to authenticate users in production environments. - -For more information, see xref:embed-authentication.adoc[Authentication]. - -== Define security settings - -Before embedding, you must enable several security settings in the Developer portal for cross-domain communication. - -Cross-Origin Resource Sharing:: -Cross-Origin Resource Sharing (CORS) domains are the origins from which ThoughtSpot APIs can be called. When you add your host domain for CORS in the Developer portal, ThoughtSpot adds the `access-control-allow-origin` header in its API responses. - -Content Security Policy:: -To use the Visual Embed SDK, configure the following content security policy (CSP). -* *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, you must add your host domain as a CSP visual embed host. -* *CSP connect-src* -+ -If you plan to configure custom actions to invoke external URLs, you must add these URLs to the *CSP connect-src* domain list in the Developer portal. - -For more information, see xref:security-settings.adoc[Configure security settings]. - -== Try out the embed modules -The ThoughtSpot Developer portal provides a playground for developers to explore the Visual Embed SDK components. The *Playground* offers an interactive coding experience for developers to evaluate the APIs and embed ThoughtSpot search, visualizations, Liveboards, or the full ThoughtSpot experience within their host application. - -++++ -Go to Playground -++++ - diff --git a/modules/ROOT/pages/intro-thoughtspot-objects.adoc b/modules/ROOT/pages/intro-thoughtspot-objects.adoc index 3096ec818..e2a2d0b9e 100644 --- a/modules/ROOT/pages/intro-thoughtspot-objects.adoc +++ b/modules/ROOT/pages/intro-thoughtspot-objects.adoc @@ -6,9 +6,9 @@ :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 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. +ThoughtSpot is a business intelligence and data analytics platform for exploring, analyzing, and sharing 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. +Review this page to understand how ThoughtSpot's architecture differs from other BI tools before proceeding with the developer documentation. == Object model hierarchy @@ -23,10 +23,100 @@ Objects have an additional `obj_id` property that is *user-settable* and *unique 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 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. +`obj_id` enables TML export and import across Orgs and instances, allowing ThoughtSpot to automatically determine the object's GUID without manual GUID mapping. + +=== Supported object types + +Currently, `obj_id` is supported for the following object types: + +// SOURCE: PRD doc section "Requirements"; SCAL-317366 description + +* Answers +* Data Model +* Logical Tables +* Liveboards +* Visualizations +* Collections +* Personalized Views + +=== obj_id format and constraints + +// SOURCE: PRD doc section "Identity Constraints and Object-ID Specification"; SCAL-314582 +`obj_id` values must meet the following requirements: + +[cols="2,3", options="header"] +|=== +|Constraint | Requirement + +|Allowed characters | Lowercase alphanumeric, dots, and hyphens: `[a-z0-9.-]` +|Casing | Strictly lowercase +|Maximum length | 64 characters +|GUID exclusion | Must not match a standard GUID format to prevent ambiguity +|=== + +*Valid examples:* `sales.pipeline.v1`, `finance-ledger-prod`, `ingestion-worker-01` + +=== obj_id resolution + +// SOURCE: PRD doc section "Deterministic Keying and Distributed Consistency"; SCAL-317366 +When an identifier is passed to a REST API endpoint that accepts an `object_identifier`, ThoughtSpot resolves it in the following order: + +. `obj_id` (user-defined identifier) +. GUID +. Name + +This resolution order enables `obj_id` to be used anywhere a GUID or name is accepted in the REST API v2.0 endpoints that support the `object_identifier` field. Backward compatibility with existing GUID-based and name-based integrations is fully maintained. + +[NOTE] +==== +`obj_id` resolution is scoped to the Org. An `obj_id` value is unique within a single Org. The `org_id` + `obj_id` combination uniquely identifies an object across the entire ThoughtSpot instance. +==== + +=== Setting and updating obj_id + +`obj_id` values can be set or updated using the following REST API endpoints: + +* `POST /api/rest/2.0/metadata/update-obj-id` + +Updates the `obj_id` for one or more metadata objects. Accepts the object's GUID (`metadata_identifier`) or its current `obj_id` (`current_obj_id`). + +// SOURCE: deploy-with-tml-apis.adoc; SCAL-317366 +[,json] +---- +{ + "metadata": [ + { + "metadata_identifier": "c1e4043a-4524-4fcb-a20f-9e7aff4dc972", + "new_obj_id": "sales-pipeline-v1" + } + ] +} +---- + +Or, using the current `obj_id`: + +[,json] +---- +{ + "metadata": [ + { + "current_obj_id": "sales-pipeline-v1-c1e4043a", + "new_obj_id": "sales-pipeline-v1" + } + ] +} +---- + +The request accepts an array, allowing multiple objects to be updated in a single API call. + +[NOTE] +==== +Objects are assigned an automatic `obj_id` after the first change to the object once the feature is enabled on your instance. The auto-generated format appends the first segment of the GUID: for example, `RetailSalesRAD-KPIs-c1e4043a`. If the `metadata_obj_id` property in the `/metadata/search` response is `null`, the object has not been updated since the feature was enabled. +==== + +For information about using `obj_id` in CI/CD workflows, see xref:deploy-with-tml-apis.adoc[Deploy with TML APIs] and xref:development-and-deployment.adoc[Development and deployment]. == Data modeling -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. +A data model requires 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] to 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 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. @@ -51,7 +141,7 @@ ThoughtSpot Search data creates a table or chart view based on the query in the 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. +A link:https://docs.thoughtspot.com/cloud/latest/liveboard[Liveboard, window=_blank] is a collection of visualizations in a defined layout. Visualizations are created from search data results and pinned to a Liveboard; they cannot be created directly within the Liveboard. New Liveboards can be created from the *Liveboards* page and visualizations from search data results added to them, or new Liveboards can be created when pinning an Answer retrieved from search data. === Content creation workflow @@ -61,9 +151,9 @@ To create content: 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 from search results to a Liveboard object. Pinned visualizations exist only within the Liveboard and are independent of objects saved as *Answers*. +Any number of visualizations from search results can be added 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. +Each time a search result is pinned, a separate new visualization is created on the Liveboard. To edit a visualization on a Liveboard: diff --git a/modules/ROOT/pages/lazy-loading-fullheight.adoc b/modules/ROOT/pages/lazy-loading-fullheight.adoc index 0d09fafb2..ed3d8c8bb 100644 --- a/modules/ROOT/pages/lazy-loading-fullheight.adoc +++ b/modules/ROOT/pages/lazy-loading-fullheight.adoc @@ -9,55 +9,62 @@ The Visual Embed SDK provides configuration options to control how embedded apps handle the height of frame and loading of visualizations on an embedded Liveboard. == Loading visualizations in the Liveboard viewport -To dynamically resize the height of the Liveboard embed container, the Visual Embed SDK provides the `fullHeight` boolean property. The `fullHeight` property dynamically adjusts the height of the embed container to match the height of the Liveboard, thereby eliminating the need for scroll bars. +To dynamically resize the height of the Liveboard embed container, the Visual Embed SDK provides the `fullHeight` property. * If `fullHeight` is set to `true`: + -The height of the Liveboard container dynamically adjusts to match the height of the Liveboard content. This causes all visualizations on the Liveboard to load simultaneously, which can lead to a potentially longer wait for the top-most visualizations to appear in the viewport. However, setting `lazyLoadFullHeight` to `true` along with `fullHeight: true` allows lazy loading for visualizations in the viewport as the user scrolls the page. The `fullHeight: true` works best when an embedded Liveboard has fewer visualizations. +The height of the Liveboard container dynamically adjusts to match the height of the Liveboard content. This causes all visualizations on the Liveboard to load simultaneously, which can lead to a potentially longer wait for the top-most visualizations to appear in the viewport. However, setting `lazyLoadingForFullHeight` to `true` along with `fullHeight: true` allows lazy loading for visualizations in the viewport as the user scrolls the page. The `fullHeight: true` works best when an embedded Liveboard has fewer visualizations. * When `fullHeight` is set to `false` (default): + Only the visualizations currently visible in the viewport are loaded initially. Additional visualizations are fetched incrementally as users scroll the page. This reduces initial load time, minimizes unnecessary data API calls, and provides a smoother, faster experience for large dashboards. By default, the `fullHeight` parameter is set to `false`. +== Lazy loading +When `fullHeight` is enabled, you can use the `lazyLoadingForFullHeight` parameter to enable lazy loading of visualizations. -=== Full height with minimum height setting -In addition to `fullHeight`, the SDK also provides the `minimumHeight` parameter. The value defined for the `minimumHeight` attribute is applied only when `fullHeight` is set to `true`. -If `fullHeight` is `true`, the embedded container resizes according to the Liveboard content . and `minimumHeight` sets the minimum height (in pixels) for this container. -This ensures that even if the Liveboard is empty or has little content, the container maintains at least the specified minimum height. If `fullHeight` is set to `false`, the `minimumHeight` attribute is not applied. +Starting with Visual Embed SDK v1.52.0, the `lazyLoadingForFullHeight` parameter is enabled by default when `fullHeight` is set to `true` and the visualizations in the embedded Liveboard are loaded incrementally as the user scrolls, rather than all at once. This reduces initial load time and resource usage, and improves performance for large Liveboards. + +If the `lazyLoadingForFullHeight` parameter is set to `false`, all visualizations load immediately, and the data is fetched upfront. [source,JavaScript] ---- -const embed = new LiveboardEmbed('#embed', { - // other liveboard view config - fullHeight: true, - minimumHeight: 600, +const embed = new LiveboardEmbed("#your-embed-div", { + liveboardId: "your-liveboard-id", //your Liveboard ID + fullHeight: true, + lazyLoadingForFullHeight: true, // Enable lazy loading for full height }); ---- -== Lazy loading with full height enabled +=== Lazy loading of scrollable container +When `fullHeight` is enabled, the `enableScrollableContainerLazyLoading` parameter is set to `true` by default to enable lazy loading for scrollable container elements in Visual Embed SDK 1.52.0 and later. + +=== Margin settings for lazy loading + +The `lazyLoadingMargin` parameter allows you to set the margin before a visualization loads in the viewport. For example, if set to `'10px'`, the visualizations begin loading when the top edge is within the 10-pixel margin of the viewport. If set to `'0px'`, the visualization loads only when it becomes fully visible in the viewport. This allows precise control over lazy loading behavior and improves both user experience and performance. + +In Visual Embed SDK 1.52.0 and later, the `lazyLoadingMargin` defaults to `'500px 0px'` when `fullHeight` is enabled. This setting is similar to CSS margin, so '500px 0px' extends the prefetch 500px above and below the viewport and not sideways. The default setting allows loading one visualization ahead of the scroll position, so a chart has usually finished loading by the time it scrolls into view. -If `fullHeight` is enabled, you can use the `lazyLoadingForFullHeight` boolean parameter to enable lazy loading of visualizations. When both `fullHeight` and `lazyLoadingForFullHeight` are set to `true`, visualizations in the embedded Liveboard are loaded incrementally as the user scrolls, rather than all at once. This reduces initial load time and resource usage, and improves performance for large Liveboards. +You can edit the margin setting as needed. Use a smaller margin to cut warehouse queries further, or '0px' to load a visualization only when it is visible. Accepted units are `px`, `em`, `rem`, `%`, `vh` and `vw`. The parameter also allows setting `0` and `auto`. Any invalid value is logged and ignored. [source,JavaScript] ---- const embed = new LiveboardEmbed("#your-embed-div", { liveboardId: "your-liveboard-id", //your Liveboard ID fullHeight: true, - lazyLoadFullHeight: true, // Enable lazy loading for full height + lazyLoadingForFullHeight: true, // Enable lazy loading for full height + lazyLoadingMargin: '0px', }); ---- -By default, the `lazyLoadingForFullHeight` attribute is set to `false`. When set to `false`, all visualizations load immediately, and the data is fetched upfront. - -== Margin settings for lazy loading +== Full height with minimum height setting +In addition to `fullHeight`, the SDK also provides the `minimumHeight` parameter to set the minimum height (in pixels) for this container. The value defined for the `minimumHeight` attribute is applied only when `fullHeight` is set to `true`. -The `lazyLoadingMargin` parameter allows you to set the margin before a visualization loads in the viewport. For example, if set to '10px', the visualizations will begin loading when the top edge is within the 10-pixel margin of the viewport. If set to '0px', the visualization will load only when it becomes fully visible in the viewport. This allows for precise control over lazy loading behavior and improves both user experience and performance. +This ensures that even if the Liveboard is empty or has little content, the container maintains at least the specified minimum height. [source,JavaScript] ---- -const embed = new LiveboardEmbed("#your-embed-div", { - liveboardId: "your-liveboard-id", //your Liveboard ID - fullHeight: true, - lazyLoadFullHeight: true, // Enable lazy loading for full height - lazyLoadingMargin: '0px', +const embed = new LiveboardEmbed('#embed', { + // other liveboard view config + fullHeight: true, + minimumHeight: 600, }); ---- diff --git a/modules/ROOT/pages/logs-api.adoc b/modules/ROOT/pages/logs-api.adoc index a6add0eff..14f230f24 100644 --- a/modules/ROOT/pages/logs-api.adoc +++ b/modules/ROOT/pages/logs-api.adoc @@ -1,15 +1,17 @@ -= Audit logs API += REST API v1 - Audit log API endpoints :toc: true :toclevels: 2 :page-title: Log streaming service -:page-pageid: logs-api +:page-pageid: logs-api-v1 :page-description: Log streaming service APIs -The log API endpoint allows you to fetch xref:audit-logs.adoc[security audit logs, window=_blank] programmatically from the ThoughtSpot system. +include::{path}/rest-apiv1-deprecation-note.adoc[] == Supported operations +The log API endpoint allows you to fetch xref:audit-logs.adoc[security audit logs, window=_blank] programmatically from the ThoughtSpot system. + include::{path}/audit-log-api.adoc[] == Required permissions diff --git a/modules/ROOT/pages/metadata-api.adoc b/modules/ROOT/pages/metadata-api.adoc index 8e3c3cc50..82f58500d 100644 --- a/modules/ROOT/pages/metadata-api.adoc +++ b/modules/ROOT/pages/metadata-api.adoc @@ -1,4 +1,4 @@ -= Metadata APIs += REST API v1 - Metadata API endpoints :toc: true :linkattrs: :toclevels: 1 @@ -6,13 +6,16 @@ :keywords: The metadata API endpoints allow you to query ThoughtSpot objects and get metadata :page-title: Get metadata -:page-pageid: metadata-api +:page-pageid: metadata-api-v1 :page-description: Metadata API -The metadata APIs allow you to query metadata objects from the ThoughtSpot system. The metadata objects include answers, Liveboards, visualizations, and data objects such as Tables, Models, and Views. You can also query metadata objects for a user or user group configured in ThoughtSpot. +include::{path}/rest-apiv1-deprecation-note.adoc[] == Supported operations +The metadata APIs allow you to query metadata objects from the ThoughtSpot system. The metadata objects include answers, Liveboards, visualizations, and data objects such as Tables, Models, and Views. You can also query metadata objects for a user or user group configured in ThoughtSpot. + + include::{path}/metadata-api-list.adoc[] === Required permissions diff --git a/modules/ROOT/pages/metadata-parameterization.adoc b/modules/ROOT/pages/metadata-parameterization.adoc index f8d9b9e0f..71d9655cd 100644 --- a/modules/ROOT/pages/metadata-parameterization.adoc +++ b/modules/ROOT/pages/metadata-parameterization.adoc @@ -1,4 +1,4 @@ -= Parameterize metadata objects += Metadata parameterization APIs :toc: true :toclevels: 2 diff --git a/modules/ROOT/pages/multi-tenancy-best-practices.adoc b/modules/ROOT/pages/multi-tenancy-best-practices.adoc index 5e3401841..43233dfcd 100644 --- a/modules/ROOT/pages/multi-tenancy-best-practices.adoc +++ b/modules/ROOT/pages/multi-tenancy-best-practices.adoc @@ -77,7 +77,7 @@ Remember to share the Model as *READ_ONLY* along with the Liveboards and answers link:https://docs.thoughtspot.com/cloud/latest/security-data-object#cls[Column level security, window=_blank] (CLS) can be configured at the individual table level through sharing. As with row-level security (RLS) groups, the best practice is to create separate groups specifically for the CLS groups. == Best practices for multi-tenant database and single-tenant database models -There are two basic architectures for storing different tenants' data within cloud data warehouses. The following sections describe a best practice starting point for deploying in ThoughtSpot depending on which of the architectures you have chosen for your CDW. REST APIs are available to deploy these patterns at scale. You can xref:group-api.adoc#create-group[create groups], xref:user-api.adoc#create-user[create users], xref:group-api.adoc#add-user-to-group[add users to groups], xref:tml-api.adoc[publish content from TML objects], and xref:security-api.adoc#share-object[share that content with the appropriate groups]. +There are two basic architectures for storing different tenants' data within cloud data warehouses. The following sections describe a best practice starting point for deploying in ThoughtSpot depending on which of the architectures you have chosen for your CDW. REST APIs are available to deploy these patterns at scale. You can xref:group-api.adoc#create-group[create groups], xref:user-api.adoc#create-user[create users], xref:group-api.adoc#add-user-to-group[add users to groups], xref:tml-import.adoc[publish content from TML objects], and xref:security-api.adoc#share-object[share that content with the appropriate groups]. === Multi-tenant database model The "multi-tenant database model" is designed on the following principles: diff --git a/modules/ROOT/pages/open-issues.adoc b/modules/ROOT/pages/open-issues.adoc index 37d91ef2c..718fc29f6 100644 --- a/modules/ROOT/pages/open-issues.adoc +++ b/modules/ROOT/pages/open-issues.adoc @@ -78,7 +78,7 @@ On exporting and reimporting TML in YAML format in the REST API v2 Playground, t This issue occurs because when reimporting TML invalid characters are added to the TML YAML content in the Playground resulting in an invalid syntax error. **Workaround**: + -See xref:tml.adoc#yamlReimport[YAML reimport in the REST API v2 Playground]. +See xref:tml-import.adoc#yamlReimport[YAML reimport in the REST API v2 Playground]. |===== diff --git a/modules/ROOT/pages/org-api.adoc b/modules/ROOT/pages/org-api.adoc index b94b2bece..788d830f4 100644 --- a/modules/ROOT/pages/org-api.adoc +++ b/modules/ROOT/pages/org-api.adoc @@ -1,11 +1,14 @@ -= Org API += REST API v1 - Org API endpoints :toc: :toclevels: 1 :page-title: Org API endpoints -:page-pageid: orgs-api +:page-pageid: orgs-api-v1 :page-description: Use Org APIs to create and manage tenant organizations on your ThoughtSpot instance +include::{path}/rest-apiv1-deprecation-note.adoc[] + + The Org API endpoints allow creating and managing multiple tenant-specific containers on a ThoughtSpot instance. Each Org object is independent of and isolated from other Org objects to support data protection and privacy. == Required permissions diff --git a/modules/ROOT/pages/org-manage-api.adoc b/modules/ROOT/pages/org-manage-api.adoc index 8b879b0d3..efea5a898 100644 --- a/modules/ROOT/pages/org-manage-api.adoc +++ b/modules/ROOT/pages/org-manage-api.adoc @@ -6,9 +6,9 @@ :page-pageid: orgs-api-op :page-description: You can administer Orgs on your mult-tenant cluster -To administer and manage Orgs, you can use the link:https://docs.thoughtspot.com/cloud/latest/orgs-overview[UI workflows, window=_blank] or REST API endpoints. +To administer and manage Orgs, you can use the link:https://docs.thoughtspot.com/cloud/latest/orgs-overview[UI workflows, window=_blank] or REST API endpoints. This article describes the REST API operations available for Org provisioning and management. -This article describes the REST API operations available for Org provisioning and management. +include::{path}/rest-apiv1-deprecation-note.adoc[] == Get started with Orgs @@ -42,6 +42,7 @@ For Orgs CRUD operations, you can also use the following REST API v2.0 Org endpo * +++/api/rest/2.0/orgs/{org_identifier}/update +++ * +++ /api/rest/2.0/orgs/{org_identifier}/delete+++ +//// === REST API v1 endpoints For Orgs CRUD operations, use the xref:org-api.adoc[`/tspublic/v1/org/`] endpoints. To access Org API endpoints, you must log in to ThoughtSpot as a cluster administrator: @@ -56,7 +57,7 @@ If the API operation is successful, ThoughtSpot creates an Org and assigns a sys + The `PUT` request allows modifying the name and description properties of an Org object. * To delete an Org object, send a `DELETE` request to the xref:org-api.adoc#deleteOrg[`/tspublic/v1/org/` endpoint] with Org ID or name in the request body. - +//// == Manage users and groups diff --git a/modules/ROOT/pages/partials/rest-apiv1-deprecation-note.adoc b/modules/ROOT/pages/partials/rest-apiv1-deprecation-note.adoc new file mode 100644 index 000000000..39bb2a047 --- /dev/null +++ b/modules/ROOT/pages/partials/rest-apiv1-deprecation-note.adoc @@ -0,0 +1,4 @@ +[IMPORTANT] +==== +The REST API v1 endpoints are deprecated and replaced with the xref:rest-api-v2-reference.adoc[REST API v2 endpoints]. Your existing integrations with REST API v1 endpoints will continue to function without disruption until further notice. ThoughtSpot strongly recommends migrating your integrations to the xref:rest-api-v2-getstarted.adoc[REST API v2 endpoints]. +==== diff --git a/modules/ROOT/pages/pinboard-export-api.adoc b/modules/ROOT/pages/pinboard-export-api.adoc index 6c2273c73..56df2cb68 100644 --- a/modules/ROOT/pages/pinboard-export-api.adoc +++ b/modules/ROOT/pages/pinboard-export-api.adoc @@ -1,11 +1,14 @@ -= Liveboard export API += REST API v1 - Liveboard export API endpoint :toc: true :toclevels: 1 :page-title: Export Liveboard as PDF -:page-pageid: liveboard-export-api +:page-pageid: liveboard-export-api-v1 :page-description: The Liveboard export API endpoint allows you to download a pinboard or its visualizations in the PDF format +include::{path}/rest-apiv1-deprecation-note.adoc[] + +== Supported operations To programmatically download a Liveboard or specific visualizations from a Liveboard as a PDF file, use the `/tspublic/v1/export/pinboard/pdf`. [NOTE] @@ -13,8 +16,6 @@ To programmatically download a Liveboard or specific visualizations from a Liveb To remove ThoughtSpot logos from the exported PDFs, contact your ThoughtSpot team. ==== -== Supported operations - [div boxAuto] -- [width="100%" cols="2,1"] diff --git a/modules/ROOT/pages/pinboarddata.adoc b/modules/ROOT/pages/pinboarddata.adoc index de8157398..35804e3a9 100644 --- a/modules/ROOT/pages/pinboarddata.adoc +++ b/modules/ROOT/pages/pinboarddata.adoc @@ -1,11 +1,13 @@ -= Liveboard data API += REST API v1 - Liveboard data API endpoint :toc: true :toclevels: 1 :page-title: Get Liveboard Data -:page-pageid: liveboard-data-api +:page-pageid: liveboard-data-api-v1 :page-description: The liveboard data API API allows you to query a pinboard and its visualizations +include::{path}/rest-apiv1-deprecation-note.adoc[] + To retrieve data related to a Liveboard or visualization from the ThoughtSpot system, you can use the Liveboard data API. Using this API, you can fetch the following information: diff --git a/modules/ROOT/pages/prerender.adoc b/modules/ROOT/pages/prerender.adoc index bf568f4cb..938e9ff7d 100644 --- a/modules/ROOT/pages/prerender.adoc +++ b/modules/ROOT/pages/prerender.adoc @@ -1,21 +1,17 @@ -= Pre-rendering ThoughtSpot Embed components += Prerender components :toc: true :toclevels: 2 -:page-title: Pre-rendering for Fast Embeds +:page-title: Prerender for fast embedding :page-pageid: prerender :page-description: How to use pre-rendering to optimize performance and user experience in ThoughtSpot embedding -Before implementing pre-rendering, let's understand how embedding ThoughtSpot works in a typical web app. - -== How embedding works - ThoughtSpot is a web app, and like any modern web application, it requires two main things to function: * *Assets* - The static files your browser needs to display and run the application, such as JavaScript files, CSS files, fonts, and images. * *API Calls*: These are network requests made from the browser to the ThoughtSpot backend to fetch: + -- Data (the actual analytics, tables, charts, and so on) -- Metadata (information about users, tables, permissions, and so on) +** Data (the actual analytics, tables, charts, and more) +** Metadata (information about users, tables, permissions, and more) image::./images/pre-render/web-app.png[] @@ -27,23 +23,23 @@ ThoughtSpot internally optimizes the loading process by splitting assets and API - For embed components such as Search, Liveboard, and Spotter, only the assets and API calls required for that component are loaded. - There are a few common assets such as fonts, shared JavaScript, CSS, and common API calls to fetch user information, that are always loaded, as they are used across all embed types. -- In addition to these common resources, each component (for example, Liveboard) will load its own specific JavaScript, CSS, and make API calls only needed for that component. +- In addition to these common resources, each component (for example, Liveboard) will load its own specific JavaScript and CSS, and make only the API calls needed for that component. image::./images/pre-render/asset-split.png[] For example, if you are embedding a Liveboard: . The browser first loads the common assets and makes common API calls for resources such as fonts and user information. -. Then, it loads the Liveboard-specific JavaScript and CSS files, and make the necessary API calls to fetch Liveboard data. -. Assets and API calls for other components, such as Search or Spotter, are not loaded unless those components are actually used. +. Then, it loads the Liveboard-specific JavaScript and CSS files, and makes the necessary API calls to fetch Liveboard data. +. Assets and API calls for other components, such as Search or Spotter, are not loaded unless those components are used. This approach ensures that the embed is efficient, loading only what is necessary for the user's current experience, and helps improve performance by reducing unnecessary downloads and network requests. -Before getting started with pre-rendering, let’s understand the essential first step in embedding ThoughtSpot. +Before getting started with pre-rendering, let's understand the essential first step in embedding ThoughtSpot. == `init` call -In ThoughtSpot embedding, `init` is first essential step. Before you can render any ThoughtSpot embed component, you must call the `init` method from the Visual Embed SDK. This function initializes the SDK and sets up the connection to your ThoughtSpot instance. It is the required starting point for any embedding scenario. +In ThoughtSpot embedding, `init` is the first essential step. Before you can render any ThoughtSpot embed component, you must call the `init` method from the Visual Embed SDK. This function initializes the SDK and sets up the connection to your ThoughtSpot instance. It is the required starting point for any embedding scenario. === When should you call `init`? @@ -60,9 +56,9 @@ Always call `init` before rendering any embed component, and do so as soon as yo == Pre-rendering overview -Now that you know how ThoughtSpot loads assets and data, let’s explore how you can make the experience even faster for your users. +Now that you know how ThoughtSpot loads assets and data, let's explore how you can make the experience even faster for your users. -Consider the scenario, where you have an app with a landing screen where users spend some time before navigating to the embedded ThoughtSpot page. In the current setup, ThoughtSpot only starts loading when the user actually visits the analytics page. What if you could start loading some of ThoughtSpot’s essential files and data while users are still on the landing screen, before they reach the analytics page? +Consider the scenario, where you have an app with a landing screen where users spend some time before navigating to the embedded ThoughtSpot page. In the current setup, ThoughtSpot only starts loading when the user visits the analytics page. What if you could start loading some of ThoughtSpot’s essential files and data while users are still on the landing screen, before they reach the analytics page? That’s exactly what pre-rendering does! By starting the load process early, you can make the analytics appear much faster when the user finally navigates to that page. @@ -72,12 +68,12 @@ image::./images/pre-render/pre-rendering-basic.png[] Keeping the above in mind, let's define a few key terms that we'll use later in this guide: -* **Common asset download** – The shared JavaScript and CSS files that every embed needs -* **Common API calls** – The basic API requests made for things like user info, used by all embed types -* **Embed level asset download** – The specific files (like JS and CSS) needed only for the embed type you're using (for example, Liveboard or Search) -* **Embed API calls** – The API requests made to fetch the actual data and content for the specific embed (like loading a Liveboard's data) -* **Host app** – This is your web application (the main app your users interact with) -* **Analytics page** – This is a page in your web app where ThoughtSpot is actually embedded +* **Common asset download**: The shared JavaScript and CSS files that every embed needs +* **Common API calls**: The basic API requests made for things like user info, used by all embed types +* **Embed level asset download**: The specific files (like JS and CSS) needed only for the embed type you're using (for example, Liveboard or Search) +* **Embed API calls**: The API requests made to fetch the actual data and content for the specific embed (like loading a Liveboard's data) +* **Host app**: This is your web application (the main app your users interact with) +* **Analytics page**: This is a page in your web app where ThoughtSpot is embedded == How to use pre-rendering? @@ -85,7 +81,7 @@ Based on your use case, you can choose to pre-render the embed in one of the fol . xref:prerender.adoc#_pre_render_with_liveboard_id[Pre-render with Liveboard ID] . xref:prerender.adoc#_pre_render_without_the_liveboard_id[Pre-render without the Liveboard ID] -. xref:prerender.adoc#_pre_render_on_demand[Prerender on demand] +. xref:prerender.adoc#_pre_render_on_demand[Pre-render on demand] . xref:prerender.adoc#_normal_render[Normal render] . xref:prerender.adoc#_prefetch_assets[Prefetch assets] @@ -100,15 +96,16 @@ In this approach, you load everything all at once. When the user navigates to th image::./images/pre-render/dig3_pre_with_livid.png[] ==== Implementation - -In your application's home page, loading page, or landing page, you need to prerender the embed with the Liveboard ID. +In your application's home page, loading page, or landing page, you need to pre-render the embed with the Liveboard ID. [source,JSX] ---- // React ---- @@ -121,20 +118,24 @@ import { LiveboardEmbed } from '@thoughtspot/visual-embed-sdk'; const embed = new LiveboardEmbed({ liveboardId: 'e40c0727-01e6-49db-bb2f-5aa19661477b', - preRenderId: 'pre-render-with-liveboard-id', + preRenderConfig: { + id: 'pre-render-with-liveboard-id', + }, }); embed.preRender(); ---- -When you actually want to show the Liveboard, call this component: +When you want to show the Liveboard, call this component: [source,JSX] ---- // React ---- @@ -147,17 +148,71 @@ import { LiveboardEmbed } from '@thoughtspot/visual-embed-sdk'; const embed = new LiveboardEmbed({ liveboardId: 'e40c0727-01e6-49db-bb2f-5aa19661477b', - preRenderId: 'pre-render-with-liveboard-id', + preRenderConfig: { + id: 'pre-render-with-liveboard-id', + }, }); embed.render(); ---- +[NOTE] +==== +Starting from Visual Embed SDK 1.52.0, the top-level pre-render properties are deprecated. Use the `preRenderConfig` object instead: + +* `preRenderId` → `preRenderConfig.id` +* `preRenderContainer` → `preRenderConfig.containerSelector` +* `doNotTrackPreRenderSize` → `preRenderConfig.doNotTrackSize` +==== + This approach is the fastest way to load the embed, but it is also the most resource-intensive. -The makes calls to the ThoughtSpot API to fetch the Liveboard data and metadata, which might be unwanted if the end user never views the embed. +The SDK makes calls to the ThoughtSpot API to fetch the Liveboard data and metadata, which might be unwanted if the end user never views the embed. + +=== Mount the pre-rendered embed in a specific container +By default, the SDK attaches pre-rendered iframes as child components of the document body. The `containerSelector` property in `preRenderConfig` tells the SDK which element on your page to mount the pre-rendered embed inside instead. + +This is useful when the browser window itself does not scroll, but an inner container does. Mounting the pre-rendered embed inside the scrolling container ensures the embed positions and sizes itself correctly within your application's layout. + +For example, if the window does not scroll, `#app-scroll` does, and the embed element sits inside it: + +[source,HTML] +---- +
+
+
+---- + +Set `containerSelector` to the scrolling container: + +[source,JavaScript] +---- +const embed = new LiveboardEmbed('#tsEmbed', { + liveboardId: '', + preRenderConfig: { + id: 'my-liveboard', + containerSelector: '#app-scroll', + }, +}); + +// Warm the Liveboard up front, for example on your landing page. +await embed.preRender(); + +// Reveal it when the user navigates to the page that shows it. +embed.showPreRender(); +---- + +In React, set `containerSelector` on the `PreRendered` component, the component that creates the pre-render: + +[source,JSX] +---- + +---- -=== Pre-render without the Liveboard ID +=== Pre-render without the Liveboard ID In this approach, you load the common assets and common API calls early, but you defer the Liveboard-specific data/API calls until needed. - Loads common assets and bootstrap logic early. @@ -172,7 +227,9 @@ To use this strategy, place the following component on your application's home p [source,JSX] ---- ---- @@ -184,18 +241,21 @@ OR import { LiveboardEmbed } from '@thoughtspot/visual-embed-sdk'; const embed = new LiveboardEmbed({ - preRenderId: 'pre-render-without-liveboard-id', + preRenderConfig: { + id: 'pre-render-without-liveboard-id', + }, }); embed.preRender(); ---- - -When you actually want to show the Liveboard, call this component: +When you want to show the Liveboard, call this component: [source,JSX] ---- ---- @@ -208,33 +268,39 @@ OR import { LiveboardEmbed } from '@thoughtspot/visual-embed-sdk'; const embed = new LiveboardEmbed({ - preRenderId: 'pre-render-without-liveboard-id', + preRenderConfig: { + id: 'pre-render-without-liveboard-id', + }, liveboardId: 'e40c0727-01e6-49db-bb2f-5aa19661477b', }); embed.render(); ---- -This approach is more efficient than the previous one, but it does not load the Liveboard data and metadata until the end user actually navigates to the analytics page. So users might see a loading state for a few seconds before the Liveboard is loaded. +This approach is more efficient than the previous one, but it does not load the Liveboard data and metadata until the end user navigates to the analytics page. So users might see a loading state for a few seconds before the Liveboard is loaded. === Pre-render on demand +If you do not want your host app to fetch any ThoughtSpot resources during its initial load, pre-rendering on demand is ideal. -If you do not want your host app to fetch any ThoughtSpot resources during its initial load, this approach is ideal. - -In this mode, nothing is fetched until you actually render the embed. On the first render, all required assets and data are loaded. The iframe is then kept alive in the browser, so subsequent renders with the same `preRenderId` are instant because the existing iframe is reused. +In this mode, nothing is fetched until you render the embed. On the first render, all required assets and data are loaded. The iframe is then kept alive in the browser, so subsequent renders with the same prerender ID are instant because the existing iframe is reused. - Loads nothing up front; the embed is created only when the end user navigates to it. -- First visit loads normally; subsequent visits with the same `preRenderId` reuse the iframe and appear instantly. +- First visit loads normally; subsequent visits with the same prerender ID reuse the iframe and appear instantly. - Most resource‑efficient; loads only if needed and avoids repeated work by reusing the iframe. - Performance benefit is realized only when the user navigates back to the analytics page; the first visit behaves like a normal render. image::./images/pre-render/dig5_ondemand.png[] -Since we are not 'preloading' any assets or data, this strategy does not require any pre-render component, simply pass a `preRenderId` prop to your normal component render. +Since we are not _preloading_ any assets or data, this strategy does not require any pre-render component. Simply pass a prerender ID in the `preRenderConfig` object of your normal component render. [source,JSX] ---- - + ---- [source,js] @@ -243,16 +309,18 @@ Since we are not 'preloading' any assets or data, this strategy does not require import { LiveboardEmbed } from '@thoughtspot/visual-embed-sdk'; const embed = new LiveboardEmbed({ - preRenderId: 'pre-render-on-demand', + preRenderConfig: { + id: 'pre-render-on-demand', + }, liveboardId: 'e40c0727-01e6-49db-bb2f-5aa19661477b', }); embed.render(); ---- -The value of `preRenderId` can be any string, but it must match the `preRenderId` you use when rendering the actual embed later. +The value of prerender ID can be any string, but it must match the `id` you use when rendering the actual embed later. -=== Normal Render +=== Normal render - Default behavior. Loads the embed only when the component is rendered. - On every visit, the iframe is recreated and the embed loads from scratch. @@ -300,24 +368,50 @@ prefetch("https://:", [ ]); ---- -== Strategy Comparison Table +== Strategy comparison table [cols="1,1,1,1,1,1,2",options="header"] |===== | Strategy | Loads in Parallel | Loads Data If Not Used | Loads Assets If Not Used | Reuses Iframe | Perceived Load Speed | Notes -| Normal Render | ❌ | ✅ No | ✅ No | ❌ | ❌ Slowest | No reuse; re-renders every time +| Normal render | ❌ | ✅ No | ✅ No | ❌ | ❌ Slowest | No reuse; re-renders every time | Prefetch | ✅ (few assets) | ✅ No | ⚠️ Yes (small assets) | ❌ | ⚠️ Slight improvement | Browser cache often makes it redundant -| Prerender + ID | ✅ | ❌ Yes | ❌ Yes | ✅ | ✅✅✅ Fastest | Best UX, worst resource efficiency -| Prerender w/o ID | ✅ | ✅ No | ⚠️ Yes (partial assets) | ✅ | ⚠️ Moderate | Trade-off between prep and efficiency +| Pre-render + ID | ✅ | ❌ Yes | ❌ Yes | ✅ | ✅✅✅ Fastest | Best UX, worst resource efficiency +| Pre-render w/o ID | ✅ | ✅ No | ⚠️ Yes (partial assets) | ✅ | ⚠️ Moderate | Trade-off between prep and efficiency | On Demand | ❌ | ✅ No | ✅ No | ✅ | ✅ (on revisit), ❌ (first visit) | Best balance of performance and efficiency |===== -=== Advanced Troubleshooting +== Best practices +When you pre-render a Liveboard with `PreRenderedLiveboardEmbed`, pass the same configuration you intend to use on the real `LiveboardEmbed`, including the `liveboardId` and any flags that change the Liveboard's layout or behavior, such as `isLiveboardCompactHeaderEnabled` or `isLiveboardMasterpiecesEnabled`. + +These settings alter the rendered UI and the API calls ThoughtSpot makes to build the Liveboard. If a flag is set on `LiveboardEmbed` but was missing from the pre-rendered instance, the pre-rendered app cannot be reused as-is: it has to reload and re-fetch the Liveboard, which cancels the benefit of pre-rendering and reintroduces exactly the delay you were trying to avoid. + +As a best practice, pre-render with the exact configuration you intend to display, the same `liveboardId`, and settings. When the pre-rendered configuration matches, the SDK reuses the existing instance directly, resulting in a near-instant load. + +[source,JSX] +---- +// Pre-render early (hidden), with the full config + + +// Later, show it — identical configuration settings, so the pre-rendered instance is reused + +---- + +== Troubleshooting * If the pre-rendered component does not appear, check that the container is visible and the coordinates are set. -* The iframes are saved as a child components to the body and not in the given target element. +* The iframes are saved as child components to the body, and not in the given target element. To mount the pre-rendered iframe inside a specific element instead, use `preRenderConfig.containerSelector`. For more information, see xref:prerender.adoc#_mount_the_pre_rendered_embed_in_a_specific_container[Mount the pre-rendered embed in a specific container]. -== Additional Resources +== Additional resources * link:https://github.com/thoughtspot/developer-examples/tree/main/visual-embed/pre-rendering[Pre-rendering examples on GitHub, window=_blank] * link:https://stackblitz.com/github/thoughtspot/developer-examples/tree/main/visual-embed/pre-rendering[StackBlitz: Pre-rendering, window=_blank] diff --git a/modules/ROOT/pages/publish-api.adoc b/modules/ROOT/pages/publish-api.adoc index eb53db085..400dc0025 100644 --- a/modules/ROOT/pages/publish-api.adoc +++ b/modules/ROOT/pages/publish-api.adoc @@ -1,8 +1,8 @@ -= Publishing content to Orgs via APIs += Publish content to Orgs via APIs :toc: true :toclevels: 2 -:page-title: Publish objects to Orgs +:page-title: Publish content to Orgs :page-pageid: publish-to-orgs :page-description: Use the publish APIs to publish a master object from a primary Org to destination Orgs on a ThoughtSpot instance diff --git a/modules/ROOT/pages/report-apis-v2.adoc b/modules/ROOT/pages/report-apis-v2.adoc new file mode 100644 index 000000000..a6f42fe91 --- /dev/null +++ b/modules/ROOT/pages/report-apis-v2.adoc @@ -0,0 +1,451 @@ += Report APIs +:toc: true +:toclevels: 3 + +:page-title: report-apis +:page-pageid: report-apis +:page-description: Report APIs + +ThoughtSpot provides the following REST API v2 endpoints to download or export data as a file: + +* xref:#_liveboard_report_api[`POST /api/rest/2.0/report/liveboard`] + +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, a pinned Answer on a Liveboard, or a Spotter-generated Answer in PDF, PNG, CSV, or XLSX file format. + +[NOTE] +To retrieve data as JSON instead of downloading a file, see xref:data-apis-v2.adoc[Data APIs]. + +== Liveboard Report API + +To download a Liveboard report via `/api/rest/2.0/report/liveboard` API, you need at least view access to the Liveboard specified in the API request. + +In the `POST` request body, specify the GUID or name of the Liveboard as `metadata_identifier`. To download reports with specific visualizations, add GUIDs or names of the visualizations in the `visualization_identifiers`. + +To download visualizations from a specific Liveboard tab, specify the name or GUID of the tab in the `tab_identifiers` parameter. + +To download a personalized view of the Liveboard, specify the view name in the `personalised_view_identifier` attribute. + +[IMPORTANT] +==== +* The downloadable file returned in the Liveboard API response is extensionless. You need to rename the downloaded file by adding the relevant extension. Answer exports are named automatically; see xref:#_answer_report_api[Answer Report API]. +* If the Liveboard includes Note tiles, ensure that you do not pass the GUID of Note tiles as `visualization_identifiers` in the API request. Attempting to do so will lead to an error, and the API will return 400 error code in response. +* Attempting to override existing filter values with runtime filters while exporting a Liveboard will result in an error. +* If Role-Based Access Control (RBAC) is disabled, `DATADOWNLOADING` (Can download Data) privilege is required for Liveboard exports. +* If the Role-Based Access Control (RBAC) is enabled, the `CAN_DOWNLOAD_DETAILED_DATA` (Can download detailed data) privilege is required to export in the XLSX or CSV formats, and the `CAN_DOWNLOAD_VISUALS` (Can download visuals) privilege is required for PDF or PNG exports. +==== + +=== File Formats + +The default `file_format` is *CSV*. + +[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, + +* 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, + +* 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. +* New pivot tables generated in .xlsx workbooks using this API endpoint retain their complete visual formatting and structural integrity. + +==== 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. + +You can now also download continuous pdfs which matches the full length of your Liveboard, without breaking them into multiple A4 pages. + +* `page_size = CONTINUOUS` Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. ++ +When `page_size = CONTINUOUS`, the `include_filter_page` option works to show/hide the filter section in the PDF page (in a continuous PDF, there is no separate filter page, but the filters are included on the same page at the top). +* `zoom_level` offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. This can be set only when `page_size = CONTINUOUS`. Valid values are integers in the range of 45 and 175. + + +==== Sample API payload for PDF downloads + +[source,cURL] +---- +curl -X POST 'https://{ThoughtSpot-Host}/api/rest/2.0/report/liveboard' \ +--header 'Authorization: Bearer {access-token}' \ +--header '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": { + "page_size": "CONTINUOUS", + "zoom_level": 105, + "include_cover_page": true, + "include_custom_logo": true, + "include_filter_page": true, + "include_page_number": true, + "page_orientation": "PORTRAIT", + "truncate_table": false, + "page_footer_text": "Sample footer text" + } +}' +---- + +For *PNG* downloads, you can now define + +* `image_resolution` +* `image_scale` +* `include_header` + +[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`. +** 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*. + +==== + +==== Sample API payload for PNG 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": "PNG", + "tab_identifiers": [ + "bc6d6fb8-1e06-4617-b02f-51745e6933a6" + ], + "png_options": { + "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. + +[source,JSON] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/liveboard' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {access-token}' \ + --data-raw '{ + "metadata_identifier": "9bd202f5-d431-44bf-9a07-b4f7be372125", + "file_format": "PNG", + "override_filters": [ + { + "column_name": "Color", + "generic_filter": { + "op": "IN", + "values": [ + "almond", + "turquoise" + ] + }, + "negate": false + }, + { + "column_name": "Commit Date", + "date_filter": { + "datePeriod": "HOUR", + "number": 3, + "type": "LAST_N_PERIOD", + "op": "EQ" + } + }, + { + "column_name": "Sales", + "generic_filter": { + "op": "BW_INC", + "values": [ + "100000", + "70000" + ] + }, + "negate": true + } + ], + "png_options": { + "include_cover_page": true, + "include_filter_page": true + } +}' +---- + +[#transient-lb-content-report] +=== Liveboard data with unsaved changes + +include::{path}/transient-lb-content.adoc[] + +==== Sample browser fetch request + +[source,JavaScript] +---- +< iframe src = "http://ts_host:port/" id = "ts-embed" > < /iframe> +< script src = "/path/to/liveboard.js" > < /script> +< script > + const embed = new LiveboardEmbed("#embed", { + frameParams: {}, + }); + async function liveboardData() { + const transientPinboardContent = await embed.trigger(HostEvent.getExportRequestForCurrentPinboard); + const liveboardDataResponse = await fetch("https://ts_host:port/api/rest/2.0/report/liveboard", { + method: "POST", + body: createFormDataObjectWith({ + "transient_content": transientPinboardContent, + }), + }); + } +< /script> +---- + +See also, link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_getexportrequestforcurrentpinboard[HostEvent.getExportRequestForCurrentPinboard]. + +== Answer Report API + +To download Answer data via `/api/rest/2.0/report/answer` API, you need at least view access to the Answer being exported. + +The API supports exporting: + +* Saved Answers +* Pinned Answers on a Liveboard +* Spotter-generated Answers + +You can download Answer data in `CSV`, `XLSX`, `PNG`, and `PDF` format. The default `file_format` is `CSV`. + +[IMPORTANT] +==== +* If Role-Based Access Control (RBAC) is disabled, the `DATADOWNLOADING` (Can download Data) privilege is required for Answer exports. +* If the Role-Based Access Control (RBAC) is enabled, the `CAN_DOWNLOAD_DETAILED_DATA` (Can download detailed data) privilege is required to export in the PDF, XLSX, or CSV formats, and the `CAN_DOWNLOAD_VISUALS` (Can download visuals) privilege is required for PNG exports. +==== + +=== Usage guidelines + +Use the `type` and `metadata_identifier` parameters together to specify the Answer to export. +The `type` parameter distinguishes between a saved Answer and a pinned Answer on a Liveboard. +If `type` is not specified, the API defaults to `SAVED`. + + +[width="100%" cols="1,2,3,2"] +|=== +|`type` |`metadata_identifier` |Result |Notes + +|`SAVED` (default) +|GUID or name of the *saved Answer* +|_Success_. Downloads the saved Answer +|Omitting `type` produces the same result as setting `type: SAVED`. + +|`PINNED` +|Container ID. represented as `viz_guid` in the TML. +|_Success_. Downloads with Liveboard context. + +Liveboard-level filters, Runtime Filters, and Column Security Rules (CSR) are automatically applied to the export. +|Use container ID (`viz_guid`) as `metadata_identifier`. +|=== + +To export a specific Personalized View of a Liveboard, include the `personalised_view_identifier` parameter with the GUID of that view. + +[NOTE] +==== +* Exported files are automatically named after the Answer title, with the file extension appended based on the selected format. +* HTML rendering is not supported for PDF exports of Answers with tables. +==== + +=== Find the metadata identifier + +For *saved Answers* (`type: SAVED`): +Send a request to `/api/rest/2.0/metadata/search` with `type: ANSWER` to retrieve the Answer GUID. + +For *pinned Answers* (`type: PINNED`): +Use the GUID of the *Liveboard* that contains the pinned Answer as the `metadata_identifier`. +To find the Liveboard GUID: + +. In the ThoughtSpot application, open the Liveboard. +. Copy the GUID from the address bar. ++ +---- +https:///#/pinboard/ +---- + +Alternatively, send a request to `/api/rest/2.0/metadata/search` with `type: LIVEBOARD`. + +=== PNG export options + +The `png_options` support the following properties: + + +[cols="1,1,3"] +|=== +|Property |Type |Description + +|`x_resolution` +|Number +|Width of the exported PNG in pixels. + +Valid range: `600px` to `3840px`. + +Default: `2254px`. This is honored only when neither `x_resolution` nor `y_resolution` is passed. If either value is passed, retaining the default 1.414:1 aspect ratio is prioritized. + +|`y_resolution` +|Number +|Height of the exported PNG in pixels. + +Valid range: `600px` to `3840px`. + +Default: `1588px`. This is honored only when neither `x_resolution` nor `y_resolution` is passed. If either value is passed, retaining the default 1.414:1 aspect ratio is prioritized. + +|`scaling` +|Integer +|Display scale percentage for objects rendered in the image. Adjusts the relative size of visual elements without cropping the image. + +Valid range: `80%` to `500%`. +|=== + +=== Examples + +==== Export a saved Answer (default) + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/answer' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ + --data-raw '{ + "metadata_identifier": "9bd202f5-d431-44bf-9a07-b4f7be372125", + "file_format": "PNG" +}' +---- + +Omitting `type` is equivalent to setting `"type": "SAVED"`. + +==== Export a pinned Answer from a Liveboard + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/answer' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ + --data-raw '{ + "metadata_identifier": "416052fd-ad22-4d48-be0a-e43b53109957", + "type": "PINNED", + "file_format": "CSV" +}' +---- + +In this case, `metadata_identifier` is the GUID of the Liveboard that contains the pinned Answer. +Liveboard-level filters, Runtime Filters, and Column Security Rules are automatically applied to the export. + +==== Export a PNG with custom dimensions and scaling + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/answer' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ + --data-raw '{ + "metadata_identifier": "9bd202f5-d431-44bf-9a07-b4f7be372125", + "file_format": "PNG", + "png_options": { + "x_resolution": 1920, + "y_resolution": 1080, + "scaling": 120 + } +}' +---- + +[#exportSpotterData] +=== Export data generated from Spotter APIs +To export results generated from Spotter APIs such as `/api/rest/2.0/ai/answer/create`, `/api/rest/2.0/ai/agent/converse/sse`, and `/api/rest/2.0/ai/conversation/{conversation_identifier}/converse`, include the session ID and generation number in the `POST` request body. + +When downloading a Spotter-generated Answer, do not specify the metadata object ID, because you will be exporting the data generated from a conversation session with Spotter and not a saved Answer. + +==== Request example + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/answer' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "file_format": "CSV", + "session_identifier": "ee077665-08e1-4a9d-bfdf-7b2fe0ca5c79", + "generation_number": 2 +}' +---- + +* `session_identifier` refers to session ID returned in the Spotter API response. +* `generation_number` indicates the Answer generation number. +* `file_format` specifies the format of the output. You can export the Spotter-generated data as PNG, CSV, XLSX, or PDF file. By default, the API exports this data in PNG file format. + +==== API Response + +If the API request is successful, ThoughtSpot returns the data in the specified file format. You can download the file to use it later or import it into your application environment. + +//// +==== Response codes +[width="100%" cols="2,4"] +[options='header'] +|=== +|HTTP status code|Description +|**200**| Successful operation +|**400**| Invalid parameter +|**401**| Unauthorized access +|**401**| Forbidden request +|**500**| Internal error +|=== +//// + +== Pagination and runtime overrides + +The Report API endpoints support the same runtime overrides as the Data API endpoints. For more information, see xref:data-apis-v2.adoc#_runtime_overrides[Runtime overrides]. + +For information about pagination, record size, and the maximum row limit that apply to the Data API endpoints, see xref:data-apis-v2.adoc#pagination[Pagination settings for Data APIs]. diff --git a/modules/ROOT/pages/rest-api-csharp-sdk.adoc b/modules/ROOT/pages/rest-api-csharp-sdk.adoc index 28200e803..ce6832f20 100644 --- a/modules/ROOT/pages/rest-api-csharp-sdk.adoc +++ b/modules/ROOT/pages/rest-api-csharp-sdk.adoc @@ -28,14 +28,14 @@ Using the .NET CLI:: [source,bash] ---- -dotnet add package ThoughtSpot.RestApi.Sdk --version 2.27.0 +dotnet add package ThoughtSpot.RestApi.Sdk --version 2.27.1 ---- Using the NuGet Package Manager console:: [source,bash] ---- -Install-Package ThoughtSpot.RestApi.Sdk -Version 2.27.0 +Install-Package ThoughtSpot.RestApi.Sdk -Version 2.27.1 ---- == API client configuration @@ -323,6 +323,7 @@ await api.ApplyConfigurationAsync(newConfig); [options="header"] |==== |ThoughtSpot release|Recommended SDK version +|ThoughtSpot Cloud: 26.9.0.cl|v2.28.0 or later |ThoughtSpot Cloud 26.8.0.cl|v2.27.1 or later |==== diff --git a/modules/ROOT/pages/rest-api-getstarted.adoc b/modules/ROOT/pages/rest-api-getstarted.adoc index ec4857c80..df6a5c918 100644 --- a/modules/ROOT/pages/rest-api-getstarted.adoc +++ b/modules/ROOT/pages/rest-api-getstarted.adoc @@ -6,11 +6,8 @@ :page-pageid: rest-api-getstarted :page-description: Get started with REST API to access, create, and manage ThoughtSpot resources programmatically. -[IMPORTANT] -==== -The REST API v1 framework has been deprecated and replaced by REST API v2 endpoints. -Existing integrations that use REST API v1 endpoints will continue to function without disruption. However, ThoughtSpot strongly recommends updating your integrations to use REST API v2 endpoints and workflows. For more information about REST API v2 endpoints, see xref:rest-api-v2-reference.adoc[REST API v2 Reference]. -==== + +include::{path}/rest-apiv1-deprecation-note.adoc[] Before you start using REST APIs, perform the following checks: diff --git a/modules/ROOT/pages/rest-api-java-sdk.adoc b/modules/ROOT/pages/rest-api-java-sdk.adoc index 2ce0cee7e..31ef6730b 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 +|ThoughtSpot Cloud: 26.9.0.cl|v2.28.0 or later |ThoughtSpot Cloud: 26.8.0.cl|v2.27.1 or later |ThoughtSpot Cloud: 26.7.0.cl|v2.26.0 or later |ThoughtSpot Cloud: 26.6.0.cl|v2.25.0 or later diff --git a/modules/ROOT/pages/rest-api-python-sdk.adoc b/modules/ROOT/pages/rest-api-python-sdk.adoc index 183851120..6a1cf354b 100644 --- a/modules/ROOT/pages/rest-api-python-sdk.adoc +++ b/modules/ROOT/pages/rest-api-python-sdk.adoc @@ -373,6 +373,7 @@ on every request. [options='header'] |==== |ThoughtSpot release version|Recommended SDK version +a|ThoughtSpot Cloud: 26.9.0.cl|v2.28.0 or later a|ThoughtSpot Cloud: 26.8.0.cl | v2.27.1 or later a|ThoughtSpot Cloud: 26.7.0.cl | v2.26.0 or later |==== diff --git a/modules/ROOT/pages/rest-api-reference.adoc b/modules/ROOT/pages/rest-api-reference.adoc index 47ae5f42a..af422063f 100644 --- a/modules/ROOT/pages/rest-api-reference.adoc +++ b/modules/ROOT/pages/rest-api-reference.adoc @@ -1,15 +1,12 @@ -= REST API v1 Reference += REST API v1 Reference (Legacy endpoints) :toc: true :page-title: REST API Reference Guide :page-pageid: rest-api-reference :page-description: REST API Reference -[IMPORTANT] -==== -The REST API v1 framework has been deprecated and replaced by REST API v2 endpoints. -Existing integrations that use REST API v1 endpoints will continue to function without disruption. However, ThoughtSpot strongly recommends updating your integrations to use REST API v2 endpoints and workflows. For more information about REST API v2 endpoints, see xref:rest-api-v2-reference.adoc[REST API v2 Reference]. -==== + +include::{path}/rest-apiv1-deprecation-note.adoc[] == Orgs management diff --git a/modules/ROOT/pages/rest-api-sdk-libraries.adoc b/modules/ROOT/pages/rest-api-sdk-libraries.adoc index c10030f94..59c6b3ce5 100644 --- a/modules/ROOT/pages/rest-api-sdk-libraries.adoc +++ b/modules/ROOT/pages/rest-api-sdk-libraries.adoc @@ -2,7 +2,7 @@ :toc: true :toclevels: 1 -:page-title: SDK libraries +:page-title: REST API SDK libraries :page-pageid: rest-api-sdk-libraries :page-description: ThoughtSpot provides SDK libraries that allow you to integrate ThoughtSpot REST APIs in your application. diff --git a/modules/ROOT/pages/rest-api-sdk-typescript.adoc b/modules/ROOT/pages/rest-api-sdk-typescript.adoc index 3710ff63d..ddcae33f9 100644 --- a/modules/ROOT/pages/rest-api-sdk-typescript.adoc +++ b/modules/ROOT/pages/rest-api-sdk-typescript.adoc @@ -201,6 +201,7 @@ const test = async () => { [options='header'] |==== |ThoughtSpot release version|Recommended SDK version +|ThoughtSpot Cloud: 26.9.0.cl|v2.28.0 or later |ThoughtSpot Cloud: 26.8.0.cl|v2.27.1 or later |ThoughtSpot Cloud: 26.7.0.cl|v2.26.0 or later |ThoughtSpot Cloud: 26.6.0.cl|v2.25.0 or later diff --git a/modules/ROOT/pages/rest-api-v1.adoc b/modules/ROOT/pages/rest-api-v1.adoc index 9f51515df..ee54a4e87 100644 --- a/modules/ROOT/pages/rest-api-v1.adoc +++ b/modules/ROOT/pages/rest-api-v1.adoc @@ -1,10 +1,12 @@ -= REST API v1 += REST API v1 (legacy framework) :toc: true :page-title: REST API v1 :page-pageid: rest-api-v1 :page-description: ThoughtSpot REST API provides service endpoints for administration, embedding, and data management. +include::{path}/rest-apiv1-deprecation-note.adoc[] + ThoughtSpot REST API v1 endpoints let you programmatically create, access, and manage ThoughtSpot objects and resources. The REST API endpoints support the following operations: * get Liveboard and visualization data from the ThoughtSpot application diff --git a/modules/ROOT/pages/rest-api-v1v2-comparison.adoc b/modules/ROOT/pages/rest-api-v1v2-comparison.adoc index 5b3352167..a48eacdcb 100644 --- a/modules/ROOT/pages/rest-api-v1v2-comparison.adoc +++ b/modules/ROOT/pages/rest-api-v1v2-comparison.adoc @@ -1,4 +1,4 @@ -= REST API v1 and v2.0 comparison += REST API v1 (legacy) and v2 framework comparison :toc: true :toclevels: 1 @@ -6,10 +6,7 @@ :page-pageid: v1v2-comparison :page-description: Difference between REST API v1 and v2.0 -[IMPORTANT] -==== -The REST API v1 framework has been deprecated and replaced by REST API v2 endpoints. The REST API v1 Playground link has also been removed from the **Develop** page in the ThoughtSpot UI in 26.6.0.cl and later versions. Existing integrations that use REST API v1 endpoints will continue to function without disruption. However, ThoughtSpot strongly recommends updating your integrations to use REST API v2 endpoints and workflows. For more information about REST API v2 endpoints, see xref:rest-api-v2-reference.adoc[REST API v2 Reference]. -==== +include::{path}/rest-apiv1-deprecation-note.adoc[] Both REST API v1 and REST API v2.0 let you access, retrieve, create, and manage ThoughtSpot objects and resources programmatically. However, the REST API v2.0 framework offers standardized request and response structures, bearer token authentication, and richer capabilities. This document lists the differences between the two versions. diff --git a/modules/ROOT/pages/rest-api-v2.adoc b/modules/ROOT/pages/rest-api-v2.adoc index c8d91a15f..b24911183 100644 --- a/modules/ROOT/pages/rest-api-v2.adoc +++ b/modules/ROOT/pages/rest-api-v2.adoc @@ -60,8 +60,6 @@ The REST API v2.0 introduces several breaking changes that may affect interopera We recommend using REST API v2.0 API endpoints for development and testing purposes in the initial release. ThoughtSpot will provide migration instructions when REST API v2.0 framework is fully ready to replace the REST API v1 endpoints in a production setup. - - == Feature limitations * The following REST API v2.0 endpoints require administrator or data download (`DATADOWNLOADING`) privilege, and at least view access to the metadata object specified in the API request. diff --git a/modules/ROOT/pages/rest-apiv1-changelog.adoc b/modules/ROOT/pages/rest-apiv1-changelog.adoc index e0bcc2d87..1ad6f51b9 100644 --- a/modules/ROOT/pages/rest-apiv1-changelog.adoc +++ b/modules/ROOT/pages/rest-apiv1-changelog.adoc @@ -6,9 +6,7 @@ :page-pageid: rest-v1-changelog :page-description: Changelog of REST APIs -This changelog lists only the changes introduced in REST API v1. For information about new embedding features and enhancements, see xref:whats-new.adoc[What's New]. - - +include::{path}/rest-apiv1-deprecation-note.adoc[] == Version 10.4.0.cl, November 2024 diff --git a/modules/ROOT/pages/rest-apiv2-changelog.adoc b/modules/ROOT/pages/rest-apiv2-changelog.adoc index 6626f8bb8..7e201fe2f 100644 --- a/modules/ROOT/pages/rest-apiv2-changelog.adoc +++ b/modules/ROOT/pages/rest-apiv2-changelog.adoc @@ -8,6 +8,91 @@ 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.9.0.cl, September 2026 + +=== Answer Export API + +The following enhancements for the `POST /api/rest/2.0/report/answer` endpoint are now GA: + +`type` parameter:: +The request body accepts a new `type` parameter that specifies the kind of Answer to export: ++ +* `SAVED` (default): exports a saved Answer. +* `PINNED`: exports a pinned Answer from a Liveboard. + +Pinned Answer export:: +Set `type` to `PINNED` to export a pinned Answer (a visualization on a Liveboard) directly. The Answer downloads with Liveboard context: Liveboard-level filters, Runtime Filters, and Column Security Rules are applied automatically. + +Personalized View support:: +Pass `personalised_view_identifier` to export data from a specific Personalized View of a Liveboard. + +Spotter Answer export:: +XLSX and PDF export formats are now supported for Spotter-generated Answers, in addition to CSV and PNG. + +Custom PNG dimensions:: +Use `x_resolution` and `y_resolution` parameters to specify custom pixel dimensions for PNG exports. + +Display scaling:: +Use `scaling` to adjust the relative size of chart elements in a PNG export without cropping the image. + +Dynamic file naming:: +Exported files are automatically named based on the Answer title with the correct file extension (`.png`, `.pdf`, `.csv`, `.xlsx`) appended. + +For more information, see xref:report-apis-v2.adoc#_answer_report_api[Answer Report API]. + +=== Snowflake Semantic View integration APIs +This release introduces the following new REST API v2.0 endpoints for managing Snowflake Semantic View integrations programmatically. + +* `POST /api/rest/2.0/semantic-integrations/create` + +Creates a new semantic integration by reading a Snowflake Semantic View and generating a ThoughtSpot data model. +* `POST /api/rest/2.0/semantic-integrations/search` + +Returns a list of semantic integrations matching the specified filter criteria. +* `POST /api/rest/2.0/semantic-integrations/{semantic_integration_identifier}/import` + +Re-imports semantic updates from Snowflake and refreshes the associated ThoughtSpot data model. +* `POST /api/rest/2.0/semantic-integrations/{semantic_integration_identifier}/delete` + +Deletes a semantic integration and its generated ThoughtSpot data model. + +For more information, see xref:semantic-integrations-api.adoc[Snowflake Semantic View integration APIs]. + +=== Conversation sharing APIs +ThoughtSpot introduces the following REST API v2.0 endpoints to share Spotter agent conversations with other users or groups. + +* `POST /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/share` + +Share a conversation with users or groups with `READ_ONLY` access. +* `GET /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/get-shared-content` + +Retrieve the shared messages and answers in a conversation. +* `GET /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/get-share-info` + +Retrieve the list of principals a conversation is shared with and their access levels. + +For more information, see xref:spotter-agent-sharing-apis.adoc[Sharing Spotter conversations]. + +=== KPI Sparkline setting in metadata search response +The `POST /api/rest/2.0/metadata/search` API response now includes the `isSparklineEnabled` parameter in the `AnswerSpecHeader` object for KPI chart type answers. This boolean parameter indicates whether the sparkline trend line is enabled for the KPI visualization. + +//// +=== Outline Encoding for Muze charts +Developers building custom charts with Muze can now bind a data field to `encoding.outline` to produce ordinal color palettes (for categorical fields) or continuous gradient ramps (for measures), with full legend rendering and legend-to-mark interaction. + +The static `outline` config (`{ fill, color, width, dash }`) remains fully backward compatible. Supported mark types: Point, Bar, Arc. +//// + +=== Personalized Views TML portability +The Personalized Views TML portability feature is now GA and enabled on all ThoughtSpot Embedded instances: + +* The `author` field in Personalized View TML maps to the view owner's username or email, ensuring ownership is retained while delegating ownership to another user during import. +* The `obj_id` field provides a stable cross-environment identifier for inter-Org deployments. +* Smart merge import: when importing a Liveboard TML that contains Personalized Views, ThoughtSpot preserves views that exist only in the target environment, appends new views from the imported TML, and updates views present in both. + +For more information, see xref:tml-import.adoc#personalized-views-portability[Personalized Views portability in TML]. + +=== Support for Scheduled Liveboards process type in Connection configuration +The connection configuration API endpoints now support `SCHEDULED_LIVEBOARDS` as a process type: + +* `POST /api/rest/2.0/connection/configuration/create` +* `PUT /api/rest/2.0/connection/configuration/{configuration_identifier}/update` + +Administrators can add `SCHEDULED_LIVEBOARDS` as a valid process type for connection configurations, allowing scheduled Liveboard delivery jobs to use an alternative connection configuration, with separate warehouse, credentials, or non-OAuth authentication instead of the parent connection's defaults. + == Version 26.8.0.cl, August 2026 === Spotter AI APIs @@ -30,7 +115,7 @@ Two new fields have been added to the TML for Personalized Views. You can see th * A new `author` field is added to the Personalized View TML during export. This field is used to assign ownership during import. * Personalized Views now carry an `obj_id` field for stable cross-environment object identity, consistent with other object types. -For more information, see xref:tml.adoc#personalized-views-portability[Personalized Views portability in TML]. +For more information, see xref:tml-import.adoc#personalized-views-portability[Personalized Views portability in TML]. Collections `obj_id` support::: // SOURCE: SCAL-317357 @@ -169,7 +254,7 @@ Stop in-progress agent response:: * `POST /api/rest/2.0/ai/agent/conversation/{conversation_identifier}/stop-response` + Stops a Spotter agent response that is currently in progress for a given conversation session. -For more information, see xref:spotter-agent-apis.adoc#_stop_an_in_progress_agent_response[Stop an in-progress agent response]. +For more information, see xref:spotter-agent-conversation-apis.adoc#_stop_an_in_progress_agent_response[Stop an in-progress agent response]. === Authentication The following new endpoints allow searching for the authentication configuration at the cluster or Org level, and also allow enabling and disabling authentication. These endpoints currently support only trusted authentication. @@ -217,7 +302,7 @@ Automatic file naming:: The API now automatically names exported files based on the Answer title and appends the correct file extension (`.png`, `.pdf`, `.csv`, or `.xlsx`). Contact ThoughtSpot Support to enable these settings for PNG downloads on your ThoughtSpot instance. -For more information, see xref:data-report-v2-api.adoc#_answer_report_api[Answer report API documentation]. +For more information, see xref:report-apis-v2.adoc#_answer_report_api[Answer report API documentation]. === Share metadata API: Collections support [beta betaBackground]^Beta^ @@ -288,7 +373,7 @@ The `POST /api/rest/2.0/report/liveboard` API endpoint enhances the PDF download * `"page_size": "CONTINUOUS"` for a seamless PDF export that matches the full length of your Liveboard. Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. * `zoom_level` offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. This can be set only when `page_size` is specified as `CONTINUOUS`. -For more information, see xref:data-report-v2-api.adoc#_liveboard_report_api[Liveboard Report API documentation]. +For more information, see xref:report-apis-v2.adoc#_liveboard_report_api[Liveboard Report API documentation]. === Metadata search API enhancements @@ -302,7 +387,7 @@ This allows you to retrieve the full list of Personalized Views associated with For more information, see xref:rest-api-v2-metadata-search.adoc#_include_personalised_views[Search metadata API]. === TML API enhancements -The previous limit of 100 Personalized Views per Liveboard on TML import has been removed. You can now import all associated Personalized Views of a Liveboard without any views being dropped. For more information, see the xref:tml-api.adoc[TML API documentation]. +The previous limit of 100 Personalized Views per Liveboard on TML import has been removed. You can now import all associated Personalized Views of a Liveboard without any views being dropped. For more information, see the xref:tml-import.adoc[TML import documentation]. == Version 26.4.0.cl, April 2026 @@ -445,7 +530,7 @@ The `same_as_parent` parameter specifies if the configuration should inherit set === 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]. +For more information, see xref:report-apis-v2.adoc[Report APIs]. === Email customization API enhancements @@ -752,7 +837,7 @@ In addition to these parameters, you can also define the following properties fo * `image_scale` * `include_header` -For more information, see xref:data-report-v2-api.adoc#_liveboard_report_api[Liveboard Report API]. +For more information, see xref:report-apis-v2.adoc#_liveboard_report_api[Liveboard Report API]. === REST API Java SDK @@ -794,7 +879,7 @@ Filters metadata objects by the user-defined object ID. This parameter returns d === Report APIs The Liveboard export API (`/api/rest/2.0/report/liveboard`) now allows overriding filters applied to a Liveboard. The `override_filters` array allows specifying several types of filters and updates the Liveboard data during export. -For more information, see xref:data-report-v2-api.adoc#_override_filters[Override filters]. +For more information, see xref:report-apis-v2.adoc#_override_filters[Override filters]. == Version 10.6.0.cl, March 2025 @@ -863,7 +948,7 @@ Allows you to specify if all objects should be imported during the TML import op * `enable_large_metadata_validation` + Indicates if the TMLs with large and complex metadata should be validated before the import. + -For more information about these attributes, see xref:tml.adoc#_import_tml_objects_asynchronously[Import TML objects asynchronously]. +For more information about these attributes, see xref:tml-import.adoc#_import_tml_objects_asynchronously[Import TML objects asynchronously]. TML import API:: @@ -925,7 +1010,7 @@ Validates and imports TML objects asynchronously. Use this API endpoint when imp * `POST /api/rest/2.0/metadata/tml/async/status` + Fetches task status for the async TML import operations. -For more information, see xref:tml.adoc#_import_tml_objects_asynchronously[Import TML objects asynchronously]. +For more information, see xref:tml-import.adoc#_import_tml_objects_asynchronously[Import TML objects asynchronously]. === API enhancements @@ -1005,7 +1090,7 @@ The `CAN_MANAGE_VERSION_CONTROL` Role privilege is required for Git integration == Version 9.12.0.cl, May 2024 -==== New features +=== New features Authentication API:: @@ -1022,7 +1107,7 @@ Allows exporting dependent Tables while exporting a Connection. * `export_connection_as_dependent` + Specifies if a Connection can be exported as a dependent object when exporting a Table, Worksheet, Answer, or Liveboard. This parameter works only when `export_associated` is set to `true` in the API request. -==== Deprecated features +=== Deprecated features Token authentication APIs:: diff --git a/modules/ROOT/pages/rest-playground.adoc b/modules/ROOT/pages/rest-playground.adoc deleted file mode 100644 index 08f6ac123..000000000 --- a/modules/ROOT/pages/rest-playground.adoc +++ /dev/null @@ -1,39 +0,0 @@ -= REST API Playground -:toc: true -:toclevels: 2 - -:page-title: REST API Playground -:page-pageid: rest-playground -:page-description: Use the REST Playground to explore the REST API endpoints, request and response workflows - -The REST API Playground provides an interactive portal to explore REST API v1 and v2.0 endpoints. - -* To view the Playground with REST API v1 endpoints, click **REST Playground v1**. + -* To explore REST API v2 endpoints, click **REST Playground v2.0**. - -== REST API v1 Playground - -The *REST Playground v1* opens the v1 API explorer and displays the available resource collections in the Swagger UI. - -To make an API call and view results: - -. Click the API service category and view a list of endpoints. -. Click on the endpoint to which you want to send an API request. -. If required, define the attributes. -. Click **Try it out** and verify the API response and HTTP status code. - -++++ -Try it out -++++ - -For more information about REST API v1 endpoints, API request and response workflow, see xref:rest-api-getstarted.adoc[Get started with REST API v1]. - -== REST API v2.0 Playground - -The REST API v2.0 Playground displays a list of v2 API endpoints, and a code panel to try out API calls. - -++++ -Try it out -++++ - -For more information, see xref:rest-api-v2-playground.adoc[REST API v2.0 Playground]. diff --git a/modules/ROOT/pages/roles-api.adoc b/modules/ROOT/pages/roles-api.adoc index ef5dbab18..6d6812f4a 100644 --- a/modules/ROOT/pages/roles-api.adoc +++ b/modules/ROOT/pages/roles-api.adoc @@ -1,14 +1,17 @@ -= Role API += REST API v1 - Role API endpoints :toc: true :toclevels: 2 :page-title: Role API -:page-pageid: role-api +:page-pageid: role-api-v1 :page-description: Use the role API endpoints to assign roles and privileges to ThoughtSpot users and groups -Use the Role API endpoints to programmatically create and manage role objects in ThoughtSpot. +include::{path}/rest-apiv1-deprecation-note.adoc[] + == Supported operations +Use the Role API endpoints to programmatically create and manage role objects in ThoughtSpot. + include::{path}/role-api-list.adoc[] == Required permissions diff --git a/modules/ROOT/pages/roles.adoc b/modules/ROOT/pages/roles.adoc index f5cc82a48..4ee8fb39d 100644 --- a/modules/ROOT/pages/roles.adoc +++ b/modules/ROOT/pages/roles.adoc @@ -170,24 +170,26 @@ UI: *Can manage variables* | Allows users to manage formula Variables in the cur === Data download control -The `DATADOWNLOADING` (**Can download Data**) Role privilege allows users to download data from objects such as Liveboards and Answers. - +If RBAC is enabled on your instance, the granular download privileges replace the single `DATADOWNLOADING` privilege. [width="100%" cols="2,4,4"] [options='header'] |=== |Role type|Privilege|Description +|Download visuals |API: `CAN_DOWNLOAD_VISUALS` + +UI: *Can download visuals* |Allows users to download data in the PDF or PNG file format. +|Data export |API: `CAN_DOWNLOAD_DETAILED_DATA` + +UI: *Can download detailed data* | Allows users to export data in XLSX or CSV file format. +|=== + + +//// |Data download | API: `DATADOWNLOADING` + UI: **Can download Data**| Allows users to download data from objects such as Liveboards and Answers. -|Download visuals [earlyAccess eaBackground]#Early Access# |API: `CAN_DOWNLOAD_VISUALS` + -UI: *Can download visuals* |Allows users to download data in the PDF or PNG file format. This is an early access feature and is not enabled by default on ThoughtSpot instances. -|Data export [earlyAccess eaBackground]#Early Access# |API: `CAN_DOWNLOAD_DETAILED_DATA` + -UI: *Can download detailed data* | Allows users to export data in XLSX/CSV format. This is an early access feature and is not enabled by default on ThoughtSpot instances. -|=== +//// + [IMPORTANT] ==== -* Contact ThoughtSpot support to enable the new `CAN_DOWNLOAD_VISUALS` and `CAN_DOWNLOAD_DETAILED_DATA` privileges. -* Once these granular privileges are enabled, the `DATADOWNLOADING` privilege will cease to exit. * Users who previously did not have `DATADOWNLOADING` privileges will not be automatically assigned the new download privileges. Administrators can assign them manually. * Users who previously had `DATADOWNLOADING` privileges will automatically be assigned both new privileges - `CAN_DOWNLOAD_VISUALS` and `CAN_DOWNLOAD_DETAILED_DATA`. ==== diff --git a/modules/ROOT/pages/runtime-filters.adoc b/modules/ROOT/pages/runtime-filters.adoc index 07a637378..d9791fbcb 100644 --- a/modules/ROOT/pages/runtime-filters.adoc +++ b/modules/ROOT/pages/runtime-filters.adoc @@ -46,28 +46,26 @@ This attribute is defined as `val1`, `val2`, `val3` in the object URLs and REST Some operators like `EQ` and `LE` accept a single operand, whereas `BW_INC_MAX`, `BW_INC_MIN`, `BW_INC`, `BW`, and `IN` accept multiple operands. === Maximum filter count +ThoughtSpot enforces separate filter count limits depending on how runtime filters are applied: -The SDK processes a maximum of 49 runtime filters per embedded object. +URL-based runtime filters:: -The internal constant `MAX_RUNTIME_FILTERS` is set to `50`, but the -parsing loop runs from index `1` up to (but not including) `50` -(`index < MAX_RUNTIME_FILTERS`). This means filter values `col1`/`op1`/`val1` -through `col49`/`op49`/`val49` are processed; `col50` and above are ignored. +URL-based runtime filters are capped at exactly 50. This limit is fixed and cannot be configured. The internal constant `MAX_RUNTIME_FILTERS` is set to `50`, but the +parsing loop runs from index `1` up to `50`. This means filter values `col1`/`op1`/`val1` +through `col50`/`op50`/`val50` are processed. -This applies to both input paths: +Embed payload runtime filters (Visual Embed SDK):: + +When you pass runtime filters as an array in the SDK initialization config for `LiveboardEmbed`, `AppEmbed`, `SpotterEmbed` and +`SearchEmbed` using the `runtimeFilters` property in the Visual Embed SDK, ThoughtSpot applies a configurable limit. The default and maximum value is 1000 runtime filters. + +Contact ThoughtSpot support to configure this limit for your instance. The value for the number of filters must be between 1 and 1000. -* URL query parameters: filter values appended to the embed URL -(`col1=`, `op1=`, `val1=`, `col2=`, …) -* `runtimeFilters` embed config property: filters passed as an array in the -SDK initialization config for `LiveboardEmbed`, `AppEmbed`, and -`SearchEmbed` [IMPORTANT] ==== -When the number of runtime filters exceeds 49, filters beyond that index are -silently dropped. No error is thrown, no warning is emitted, and no embed -event is fired. The embedded object renders using only the first 49 filters -without any indication that additional filters were discarded. This silent-drop behavior means that, if your application passes 60 runtime filters, the last 11 are ignored without any notification to the developer. Always validate filter counts in your application before passing them to the SDK. +* Regardless of the filter path, filters beyond the enforced limit are silently dropped. No error is thrown, no warning is emitted, and no embed event is fired. The embedded object renders using only the filters within the allowed count. Always validate filter counts in your application before passing them to the SDK. +* Runtime filters must be numbered sequentially, starting from `col1`. The parser reads filters in order, like `col1`, `col2`, `col3`, and stops as soon as a number is missing. ==== === Supported data types diff --git a/modules/ROOT/pages/runtime-overrides.adoc b/modules/ROOT/pages/runtime-overrides.adoc index 4176940fc..44093dd9d 100644 --- a/modules/ROOT/pages/runtime-overrides.adoc +++ b/modules/ROOT/pages/runtime-overrides.adoc @@ -21,11 +21,14 @@ Developers can set runtime filters in the Visual Embed SDK for the following emb After the object loads, runtime filters can be xref:runtime-filters.adoc#_adjust_runtime_filters_using_sdk_events[adjusted using the SDK events]. -WARNING: The SDK processes at most 49 entries per embed. Any objects at index 50 or -beyond are silently dropped without an error or warning. See -xref:runtime-filters.adoc#_maximum_filter_count[Runtime filter limit] for -more information. - +[IMPORTANT] +==== +Runtime filter limits vary by input path. URL-based runtime filters are capped at 50. +When using the Visual Embed SDK `runtimeFilters` property, the limit is configurable by a +ThoughtSpot administrator, with a default and maximum of 1,000 runtime filters. Filters beyond the enforced +limit are silently dropped without an error or warning. See +xref:runtime-filters.adoc#_maximum_filter_count[Runtime filter limit] for more information. +==== == Runtime Parameters Parameters allow users to visualize data by running different scenarios with adjustable values. You can use Parameters within formulas when analyzing your data via Search, Liveboards, or Answers. diff --git a/modules/ROOT/pages/search-data-api.adoc b/modules/ROOT/pages/search-data-api.adoc index 111e465d0..5aae26e31 100644 --- a/modules/ROOT/pages/search-data-api.adoc +++ b/modules/ROOT/pages/search-data-api.adoc @@ -1,14 +1,15 @@ -= Search data API += REST API v1 - Search data API endpoint :toc: true :toclevels: 2 :page-title: Search Data API -:page-pageid: search-data-api +:page-pageid: search-data-api-v1 :page-description: Search Data API -To construct a search query string and retrieve data from ThoughtSpot programmatically, use the `/tspublic/v1/searchdata` REST API. +include::{path}/rest-apiv1-deprecation-note.adoc[] == Supported operations +To construct a search query string and retrieve data from ThoughtSpot programmatically, use the `/tspublic/v1/searchdata` REST API. include::{path}/search-api-list.adoc[] diff --git a/modules/ROOT/pages/security-api.adoc b/modules/ROOT/pages/security-api.adoc index b703b5852..58e67f914 100644 --- a/modules/ROOT/pages/security-api.adoc +++ b/modules/ROOT/pages/security-api.adoc @@ -1,14 +1,17 @@ -= Security APIs += REST API v1 - Security API endpoints :toc: true :toclevels: 1 :page-title: Security API -:page-pageid: security-api +:page-pageid: security-api-v1 :page-description: security API -The Security APIs allow you to share ThoughtSpot objects, such as Liveboards and visualizations, with another user or a user group. Any ThoughtSpot user can share objects with another user or user group. + +include::{path}/rest-apiv1-deprecation-note.adoc[] + == Supported operations +The Security APIs allow you to share ThoughtSpot objects, such as Liveboards and visualizations, with other users or user groups in ThoughtSpot. include::{path}/security-api-list.adoc[] diff --git a/modules/ROOT/pages/security-settings.adoc b/modules/ROOT/pages/security-settings.adoc index 960f6d97d..f60a77208 100644 --- a/modules/ROOT/pages/security-settings.adoc +++ b/modules/ROOT/pages/security-settings.adoc @@ -359,7 +359,6 @@ curl -X POST \ }' ---- -//// [#custom-app-schemes] ==== Allow custom app schemes for mobile and hybrid embeds If you are embedding ThoughtSpot in a mobile or hybrid application built with frameworks such as Capacitor or Ionic, your application may use a custom URL scheme (for example, `capacitor://localhost` or `ionic://localhost`) rather than an `https://` origin. @@ -449,7 +448,6 @@ init({ .then(d => d.token), }); ---- -//// [#csp-cors-hosts] ==== Domain name format for CSP and CORS configuration @@ -501,11 +499,11 @@ If your domain URL has a non-standard port, for example `mysite.com:8080`, make |[tag greenBackground tick]#✓# Supported |[tag greenBackground tick]#✓# Supported 2*|[tag greenBackground tick]#✓# Supported -//|URLs with custom schemes such as: + -//`capacitor://localhost` + -//`ionic://localhost` +|URLs with custom schemes such as: + +`capacitor://localhost` + +`ionic://localhost` -//|[tag greenBackground tick]#✓# Supported |[tag greenBackground tick]#✓# Supported a|[tag greenBackground tick]#✓# Supported |[tag greenBackground tick]#✓# Supported +|[tag greenBackground tick]#✓# Supported |[tag greenBackground tick]#✓# Supported a|[tag greenBackground tick]#✓# Supported |[tag greenBackground tick]#✓# Supported |Wildcard (`\*`), (`.*`) for domain URL + |[tag greenBackground tick]#✓# Supported |[tag greenBackground tick]#✓# Supported a|[tag orangeBackground tick]#✓# Partial + diff --git a/modules/ROOT/pages/semantic-integrations-api.adoc b/modules/ROOT/pages/semantic-integrations-api.adoc new file mode 100644 index 000000000..0a9f80a9e --- /dev/null +++ b/modules/ROOT/pages/semantic-integrations-api.adoc @@ -0,0 +1,376 @@ += Snowflake Semantic View integration APIs +:toc: true +:toclevels: 3 + +:page-title: Snowflake Semantic View integration APIs +:page-pageid: semantic-integrations-api +:page-description: Use the ThoughtSpot REST API v2.0 endpoints to create, search, import, and delete Snowflake Semantic View integration configurations programmatically. + +ThoughtSpot provides the Semantic View integrations REST API v2.0 endpoints to create, search, import, and delete semantic integration configurations programmatically. + +== Overview +Snowflake Semantic Views provide a governed semantic layer for data in Snowflake, including named measures, dimensions, and business-logic formulas. When you create a semantic integration in ThoughtSpot, the platform reads the semantic view definition from Snowflake and generates a corresponding ThoughtSpot data model (Worksheet). The model inherits the column names, descriptions, and formula definitions from the Snowflake Semantic View. + +You can use the semantic integration APIs to automate the following tasks: + +* Create a semantic integration that links a Snowflake Semantic View to a ThoughtSpot data model. +* Search and list existing semantic integrations. +* Re-import a semantic integration to refresh the ThoughtSpot model after the source Snowflake Semantic View has changed. +* Delete a semantic integration and its generated ThoughtSpot model. + +[NOTE] +==== +The semantic integration APIs are available on ThoughtSpot Cloud instances from 26.9.0.cl. +Snowflake is the only supported CDW connector type (`RDBMS_SNOWFLAKE`). +==== + +== Prerequisites + +To use these APIs, the authenticated user must have one of the following privileges: + +* `ADMINISTRATION` (*Can administer ThoughtSpot*) +* `DATAMANAGEMENT` (*Can manage data*) + +If Role-Based Access Control (RBAC) is enabled on your instance, the user requires `CAN_CREATE_OR_EDIT_CONNECTIONS` (*Can create/edit Connections*) privilege. + +== API endpoints + +[width="100%"] +[options="header"] +|===== +| Method | Endpoint | Description +| `POST` | `/api/rest/2.0/semantic-integrations/create` | Creates a new semantic integration by reading a Snowflake Semantic View and generating a ThoughtSpot data model. +| `POST` | `/api/rest/2.0/semantic-integrations/search` | Returns a list of semantic integrations matching the specified filter criteria. +| `POST` | `/api/rest/2.0/semantic-integrations/{semantic_integration_identifier}/import` | Re-imports semantic updates from the CDW source and refreshes the associated ThoughtSpot data model. +| `POST` | `/api/rest/2.0/semantic-integrations/{semantic_integration_identifier}/delete` | Deletes a semantic integration and its generated ThoughtSpot data model. +|===== + +[#create-semantic-integration] +== Create a semantic integration +To create a new semantic integration by reading the specified Snowflake Semantic View and generating a corresponding ThoughtSpot data model, use the `/api/rest/2.0/semantic-integrations/create` API endpoint. On success, the response includes the integration GUID, the generated model GUID, and a per-formula import report. + + +=== Request parameters + +[width="100%"] +[options="header"] +|===== +| Parameter | Type | Required | Description +| `connection_identifier` | String | Yes | GUID or name of the Snowflake connection in ThoughtSpot. +| `name` | String | Yes | Display name for the semantic integration. Must be unique. +| `database_name` | String | Yes | Database name in the Snowflake CDW that contains the semantic view. +| `schema_name` | String | Yes | Schema name in the Snowflake CDW that contains the semantic view. +| `semantic_view_name` | String | Yes | Name of the Snowflake Semantic View to integrate. +| `type` | String | Yes | CDW connector type. Only accepted value: `RDBMS_SNOWFLAKE`. +| `description` | String | No | Optional description for the semantic integration. +| `tags` | Array | No | Tag GUIDs or names to associate with the integration. +|===== + +=== Response fields + +[width="100%"] +[options="header"] +|===== +| Field | Type | Description +| `id` | String | GUID of the newly created semantic integration. +| `name` | String | Display name of the semantic integration. +| `model_id` | String | GUID of the ThoughtSpot data model generated for this integration. +| `model_name` | String | Display name of the generated ThoughtSpot data model. +| `semantic_report` | Object | Per-formula import report. See <<_semantic_report_fields>>. +|===== + +[#semantic-report-fields] +=== Semantic report fields + +The `semantic_report` object contains a summary and a list of per-formula import results. + +`summary` fields: + +[width="100%"] +[options="header"] +|===== +| Field | Type | Description +| `total` | Integer | Total number of formulas in the Snowflake Semantic View. +| `imported` | Integer | Number of formulas successfully imported. +| `failed` | Integer | Number of formulas that failed to import. +| `skipped` | Integer | Number of formulas that were skipped. +|===== + +`formulas` array — each entry contains: + +[width="100%"] +[options="header"] +|===== +| Field | Type | Description +| `id` | String | Formula GUID in the generated ThoughtSpot model. +| `name` | String | Formula name. +| `description` | String | Formula description. +| `source_expression` | String | Original CDW expression. +| `translated_formula` | String | Equivalent ThoughtSpot formula expression. +| `import_status` | String | One of `IMPORTED`, `FAILED`, or `SKIPPED`. +| `change_status` | String | One of `NEW`, `UPDATED`, or `UNCHANGED`. Null on initial create (populated by import). +|===== + +=== Example request + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/semantic-integrations/create' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "connection_identifier": "", + "name": "Sales Semantic View", + "database_name": "SALES_DB", + "schema_name": "PUBLIC", + "semantic_view_name": "SALES_SEMANTIC_VIEW", + "type": "RDBMS_SNOWFLAKE", + "description": "Semantic integration for the Sales Snowflake Semantic View" +}' +---- + +=== Example response + +[source,JSON] +---- +{ + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Sales Semantic View", + "model_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", + "model_name": "Sales Semantic View", + "semantic_report": { + "summary": { + "total": 5, + "imported": 4, + "failed": 0, + "skipped": 1 + }, + "formulas": [ + { + "id": "formula-guid-001", + "name": "Total Revenue", + "description": "Sum of all revenue", + "source_expression": "SUM(revenue)", + "translated_formula": "sum(revenue)", + "import_status": "IMPORTED", + "change_status": null + } + ] + } +} +---- + +[#search-semantic-integrations] +== Search semantic integrations + +To fetch a paginated list of semantic integrations matching the specified criteria, use the `/api/rest/2.0/semantic-integrations/search` API endpoint. Returns all integrations if no filters are specified. + +=== Request parameters + +[width="100%"] +[options="header"] +|===== +| Parameter | Type | Required | Description +| `pattern` | String | No | Substring filter to narrow search results by integration name. +| `author_identifiers` | Array | No | Filter by the GUID or username of the user who created the integration. +| `connection_identifiers` | Array | No | Filter by the GUID or name of the Snowflake connection associated with the integration. +| `sort_options` | Object | No | Sort configuration. See <<_sort_options>>. +| `record_offset` | Integer | No | Number of records to skip for pagination. Minimum: 0. Default: 0. +| `record_size` | Integer | No | Maximum number of records to return. Use `0` to return all records. Default: 10. +|===== + +[#sort-options] +==== Sort options + +[width="100%"] +[options="header"] +|===== +| Field | Type | Description +| `field_name` | String | Sort field. One of: `NAME`, `AUTHOR`, `CREATED_TIME`, `MODIFIED_TIME`. +| `order` | String | Sort direction. `ASC` for ascending, `DESC` for descending. +|===== + +=== Response fields + +Returns an array of objects, each with the following fields: + +[width="100%"] +[options="header"] +|===== +| Field | Type | Description +| `id` | String | GUID of the semantic integration. +| `name` | String | Display name of the semantic integration. +| `description` | String | Description of the semantic integration. Null if not set. +| `model_id` | String | GUID of the associated ThoughtSpot data model. +| `model_name` | String | Display name of the associated ThoughtSpot data model. +| `import_type` | String | How the semantic definition was sourced. `CDW` for Snowflake Semantic View; `FILE` for file upload. +| `type` | String | CDW connector type. Currently always `RDBMS_SNOWFLAKE`. +| `connection_id` | String | GUID of the Snowflake connection. +| `connection_name` | String | Display name of the Snowflake connection. +| `author_id` | String | GUID of the user who created the integration. +| `author_name` | String | Username of the user who created the integration. +| `creation_time_in_millis` | Float | Creation time in Unix epoch milliseconds. +| `modification_time_in_millis` | Float | Last modification time in Unix epoch milliseconds. +| `tags` | Array | Tags associated with the integration, each with `id` and `name`. +|===== + +=== Example request + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/semantic-integrations/search' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "connection_identifiers": [""], + "sort_options": { + "field_name": "MODIFIED_TIME", + "order": "DESC" + }, + "record_size": 20, + "record_offset": 0 +}' +---- + +[#import-semantic-integration] +== Import a semantic integration +To re-import semantic updates from the Snowflake CDW source for an existing integration, and rebuild the corresponding ThoughtSpot data model, send a `POST` request to the `/api/rest/2.0/semantic-integrations/{semantic_integration_identifier}/import` API endpoint. Send this API request, after the source Snowflake Semantic View has been updated (formulas added, removed, or modified) to bring the ThoughtSpot model back in line with the CDW definition. + +[NOTE] +==== +Importing updates is not supported for integrations created using the file upload option in the ThoughtSpot UI. To refresh a file-upload-based integration, use the ThoughtSpot UI. +==== + +The import operation: + +* Preserves the integration GUID, name, and `model_id`. Only the formula set is refreshed. +* Returns the same `semantic_report` response as create, with an additional `change_status` per formula indicating whether each formula is `NEW`, `UPDATED`, or `UNCHANGED` since the previous import. + + +=== Path parameters + +[width="100%"] +[options="header"] +|===== +| Parameter | Type | Required | Description +| `semantic_integration_identifier` | String | Yes | GUID or name of the semantic integration to re-import. +|===== + +=== Response fields + +Same as <>, with the addition of the `change_status` field in each formula entry: + +[width="100%"] +[options="header"] +|===== +| `change_status` value | Description +| `NEW` | Formula is new since the previous import. +| `UPDATED` | Formula definition changed since the previous import. +| `UNCHANGED` | Formula is unchanged since the previous import. +|===== + +=== Example request + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/semantic-integrations/Sales%20Semantic%20View/import' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + --data-raw '{}' +---- + +=== Example response + +[source,JSON] +---- +{ + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "name": "Sales Semantic View", + "model_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", + "model_name": "Sales Semantic View", + "semantic_report": { + "summary": { + "total": 6, + "imported": 5, + "failed": 0, + "skipped": 1 + }, + "formulas": [ + { + "id": "formula-guid-001", + "name": "Total Revenue", + "description": "Sum of all revenue", + "source_expression": "SUM(revenue)", + "translated_formula": "sum(revenue)", + "import_status": "IMPORTED", + "change_status": "UNCHANGED" + }, + { + "id": "formula-guid-002", + "name": "Net Profit", + "description": "Revenue minus costs", + "source_expression": "SUM(revenue) - SUM(costs)", + "translated_formula": "sum(revenue) - sum(costs)", + "import_status": "IMPORTED", + "change_status": "NEW" + } + ] + } +} +---- + +[#delete-semantic-integration] +== Delete a semantic integration +To permanently delete the specified semantic integration and its generated ThoughtSpot data model from the system, use the `/api/rest/2.0/semantic-integrations/{semantic_integration_identifier}/delete` API endpoint. + +[WARNING] +==== +Deletion is permanent and cannot be undone. If you need to restore the integration, use the `create` endpoint to re-import the Snowflake Semantic View. +==== + +=== Path parameters + +[width="100%"] +[options="header"] +|===== +| Parameter | Type | Required | Description +| `semantic_integration_identifier` | String | Yes | GUID or name of the semantic integration to delete. +|===== + +=== Example request + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/semantic-integrations/Sales%20Semantic%20View/delete' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + --data-raw '{}' +---- + +A successful delete returns HTTP `200` with an empty response body. + +== Error responses + +[width="100%"] +[options="header"] +|===== +| Code | Description +| 400 | Bad Request — required parameter missing or invalid value (for example, unsupported `type`). +| 401 | Unauthorized — authentication token missing, expired, or invalid. +| 403 | Forbidden — the caller lacks the required privilege. +| 404 | Not Found — no semantic integration exists with the given identifier. +|===== + +== Related resources + +* xref:connections.adoc[Data connections] +* xref:rest-apiv2-changelog.adoc[REST API v2.0 changelog] +* xref:rest-api-v2-reference.adoc[REST API v2.0 reference] diff --git a/modules/ROOT/pages/session-api.adoc b/modules/ROOT/pages/session-api.adoc index 7082250fa..1fd3b2ea7 100644 --- a/modules/ROOT/pages/session-api.adoc +++ b/modules/ROOT/pages/session-api.adoc @@ -1,14 +1,16 @@ -= Session APIs += REST API v1 - Session API endpoints :toc: :toclevels: 1 :page-title: Session API -:page-pageid: session-api +:page-pageid: session-api-v1 :page-description: To log in to ThoughtSpot and create user sessions, use the session API endpoints -The Session APIs allow ThoughtSpot users to authenticate and manage their sessions. +include::{path}/rest-apiv1-deprecation-note.adoc[] == Supported operations +The Session APIs allow ThoughtSpot users to authenticate and manage their sessions. + include::{path}/session-api-list.adoc[] === Required permissions diff --git a/modules/ROOT/pages/set-default-page.adoc b/modules/ROOT/pages/set-default-page.adoc index ee51073cf..2d2d1661e 100644 --- a/modules/ROOT/pages/set-default-page.adoc +++ b/modules/ROOT/pages/set-default-page.adoc @@ -1,4 +1,4 @@ -= Customize default page and navigation path += Set default landing page and navigation :toc: true :toclevels: 2 @@ -16,8 +16,10 @@ The `pageId` parameter in `AppEmbed` sets the default ThoughtSpot page to load u * `Page.Search` for the ThoughtSpot *Search* page + * `Page.Answers` for the *Answers* page + * `Page.Liveboards` for the *Liveboards* page + +* * `Page.Data` for the *Data* page + * `Page.SpotIQ` for the *SpotIQ* analyses page +* `Page.Collections` for the *Collections* list page === Example @@ -66,6 +68,10 @@ The `path` parameter allows setting the default ThoughtSpot application page usi * `path: "monitor"` + * `path: "home/monitor-alerts"` + * `path: "insights/monitor-alerts"` +|Collections|`path: "collections"`| Supported settings include: + +* `path: "collections"` + +* `path: "home/collections"` + |===== === Example diff --git a/modules/ROOT/pages/spotdev-portal.adoc b/modules/ROOT/pages/spotdev-portal.adoc deleted file mode 100644 index 81bfc50dc..000000000 --- a/modules/ROOT/pages/spotdev-portal.adoc +++ /dev/null @@ -1,101 +0,0 @@ -= ThoughtSpot Developer portal -:toc: true - -:page-title: ThoughtSpot Developer Portal -:page-pageid: spotdev-portal -:page-description: Using ThoughtSpot Developer Portal - -ThoughtSpot Developer portal lets you explore the Visual Embed SDK, REST API SDK and preview the coding experience in Playground. - -The portal also allows authorized you to customize and rebrand the look and feel of the UI, create custom actions, and configure security and authentication settings. - -If you are an existing ThoughtSpot user:: -You can access the Developer portal from your ThoughtSpot application instance. -. Log in to ThoughtSpot. -. Navigate to the **Develop** tab. -+ -The *Develop* tab is available only if your user account has developer or administrator privilege. For more information about configuring developer privilege, see the xref:user-roles.adoc[Developer access]. - -If you are not an existing ThoughtSpot user:: -If you do not have a ThoughtSpot user account and you want to evaluate the APIs in the developer playground: -. Go to link:https://developers.thoughtspot.com/[developers.thoughtspot.com, window=_blank]. -. From the header bar, click *Playground*. - -[NOTE] -==== -You can also link:https://www.thoughtspot.com/trial?tsref=trialtsefaq[register for a free trial, window=_blank] and evaluate the SDK and APIs on ThoughtSpot free trial cluster. -==== - -== Find your way around - -The ThoughtSpot Developer portal includes several sections that assist you through your embedding journey. - -Home:: -The *Home* page of the Developer portal provides a pictorial view of ThoughtSpot features that you can integrate with your applications. -This page also includes links to the *Developer Guides* and *Playground*. - -+ -[.bordered] -image::./images/develop-home.png[Developer Portal] - - -Visual Embed SDK:: - -Includes the following menu items: - -Guide;; -Opens the Visual Embed documentation page. - -Playground;; -The Visual Embed SDK *Playground* allows you to explore the following Visual Embed components: -* xref:developer-playground.adoc#playground-search[Search] -* xref:developer-playground.adoc#playground-liveboard[Liveboards] -* xref:developer-playground.adoc#playground-visualization[Visualizations] -* xref:developer-playground.adoc#playground-fullapp[Full application] - -+ -++++ -Visit the Playground -++++ - -REST API:: -Includes the following menu items: - -Guide;; -Opens the REST API documentation. - -REST Playground v1;; -Opens the REST API v1 Explorer page. This page allows you to make API calls to the REST API v1 endpoints through the Swagger UI. -+ -++++ -Try it out -++++ - -REST Playground v2.0;; -Opens the REST API v2.0 Playground, which allows you to view the v2.0 endpoints, make API calls, and explore the request and response workflows. -+ -++++ -Try it out -++++ - -Customizations:: -The Developer portal displays the following customization options for Thoughtspot embedded instances: - -* *Styles* -+ -Provides a set of style customization controls to rebrand the look and feel of the ThoughtSpot UI and its elements. -+ -For more information, see xref:customize-style.adoc[Customize styles]. - -* *Custom actions* -+ -Provides UI workflows to create custom actions in the ThoughtSpot UI. For example, you can create an action that triggers a callback to your host application, or invoke a URL to send ThoughtSpot data. For more information, see xref:custom-actions.adoc[Custom actions]. - -* *Security settings* -+ - -Provides security controls to add third-party domains as xref:security-settings.adoc[trusted hosts for CORS and CSP]. The *Security settings* page also allows you to xref:trusted-authentication.adoc[enable trusted authentication] and xref:configure-saml.adoc[add a SAML redirect domain] to the allowed list of domains. - -* *Links settings* -+ -Allows you to customize the format of system-generated links. For more information, see xref:customize-links.adoc[Customize links]. diff --git a/modules/ROOT/pages/spotter-agent-apis.adoc b/modules/ROOT/pages/spotter-agent-apis.adoc index 5ea2587af..b664b5e0e 100644 --- a/modules/ROOT/pages/spotter-agent-apis.adoc +++ b/modules/ROOT/pages/spotter-agent-apis.adoc @@ -1,4 +1,4 @@ -= Spotter Agent APIs += Spotter AI Agent APIs :toc: true :toclevels: 2 @@ -6,10 +6,10 @@ :page-pageid: spotter-agent-apis :page-description: You can use Spotter REST APIs to receive Answers for your analytical queries sent through the conversational experience with ThoughtSpot. -ThoughtSpot's Spotter Agent APIs allow users to start a conversation session with Spotter Agent and send queries to explore data and receive responses synchronously or as a real-time Server-Sent Events (SSE) stream. +ThoughtSpot's Spotter AI agent APIs allow users to start a conversation session with Spotter Agent and send queries to explore data and receive responses synchronously or as a real-time Server-Sent Events (SSE) stream. == Overview -Spotter Agent APIs support conversation sessions with natural language query strings, provide context-aware and guided data analysis, and allow integration with other agentic systems. +Spotter AI agent APIs support conversation sessions with natural language query strings, provide context-aware and guided data analysis, and allow integration with other agentic systems. The key capabilities of the Spotter APIs include the following: @@ -19,48 +19,60 @@ The key capabilities of the Spotter APIs include the following: * Recommending relevant datasets or data sources * Decomposing complex user queries -== API endpoints - -The AI REST API endpoints listed in the following table provide all the functionality necessary to implement a Spotter 3 conversational experience in your application, from data source discovery through to streaming query responses. +== Supported API endpoints The API endpoints introduced for Spotter 2 also support Spotter 3 capabilities as of version 26.2.0.cl. Some of these API endpoints are deprecated in 26.5.0.cl; ThoughtSpot recommends using the new API endpoints instead. Initialize session:: -Call the create agent conversation API (`/api/rest/2.0/ai/agent/conversation/create`) with a data source ID to establish the session context. When auto mode is enabled, and no data source ID is specified in the API request, Spotter will automatically identify the appropriate data source. +Call the create agent conversation API (`/api/rest/2.0/ai/agent/conversation/create`) with a data source ID to establish the session context. When auto mode is enabled, and no data source ID is specified in the API request, Spotter will automatically identify the appropriate data source. See xref:spotter-agent-conversation-apis.adoc[Spotter agent conversation APIs]. Execute queries:: -To execute queries and generate a standard response synchronously, use the Send agent conversation message API (`/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send`). The send agent message API (`/api/rest/2.0/ai/agent/{conversation_identifier}/converse`) is deprecated in 26.5.0.cl and later versions. +To execute queries and generate a standard response synchronously, use the Send agent conversation message API (`/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send`). The send agent message API (`/api/rest/2.0/ai/agent/{conversation_identifier}/converse`) is deprecated in 26.5.0.cl and later versions. See xref:spotter-agent-conversation-apis.adoc[Spotter agent conversation APIs]. Real-time output (streaming):: -To stream responses to the application UI in real-time, use the `POST /api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send/stream`. The legacy streaming API (`/api/rest/2.0/ai/agent/converse/sse`) is deprecated in 26.5.0.cl and later versions. +To stream responses to the application UI in real-time, use the `POST /api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send/stream`. The legacy streaming API (`/api/rest/2.0/ai/agent/converse/sse`) is deprecated in 26.5.0.cl and later versions. See xref:spotter-agent-streaming-apis.adoc[Spotter agent streaming APIs]. + +Share a conversation:: +Share a saved Spotter conversation with other users or groups as read-only content. See xref:spotter-agent-sharing-apis.adoc[Spotter agent conversation sharing APIs]. -=== Supported API endpoints [width="100%" cols="1"] |===== a|`POST /api/rest/2.0/ai/agent/conversation/create` + -xref:spotter-agent-apis.adoc#_create_a_conversation_session_with_spotter_agent[Creates a conversation session with the Spotter agent] to generate Answers for the specified data context. +xref:spotter-agent-conversation-apis.adoc#_create_a_conversation_session_with_spotter_agent[Creates a conversation session with the Spotter agent] to generate Answers for the specified data context. __Available on ThoughtSpot Cloud instances from 10.13.0.cl onwards. Breaking changes introduced in 26.5.0.cl.__ a| `POST /api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send` [.version-badge.new]#New# + -xref:spotter-agent-apis.adoc#_send_queries_to_a_conversation_session[Sends natural language messages] to an existing Spotter agent conversation and returns the complete response synchronously. +xref:spotter-agent-conversation-apis.adoc#_send_queries_to_a_conversation_session[Sends natural language messages] to an existing Spotter agent conversation and returns the complete response synchronously. __Replaces /api/rest/2.0/ai/agent/{conversation_identifier}/converse__. a|`POST /api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send/stream` [.version-badge.new]#New# + -xref:spotter-agent-apis.adoc#_send_a_query_to_agent_and_get_streaming_responses[Sends one or more natural language messages] to an existing Spotter agent conversation and returns the response as a real-time Server-Sent Events (SSE) stream. +xref:spotter-agent-streaming-apis.adoc[Sends one or more natural language messages] to an existing Spotter agent conversation and returns the response as a real-time Server-Sent Events (SSE) stream. __Replaces /api/rest/2.0/ai/agent/converse/sse__. a|`POST /api/rest/2.0/ai/agent/conversation/{conversation_identifier}/stop-response` [.version-badge.new]#New# + -xref:spotter-agent-apis.adoc#_stop_an_in_progress_agent_response[Stops an in-progress Spotter agent response] for a given conversation session. The conversation session remains active after the response stops. + +xref:spotter-agent-conversation-apis.adoc#_stop_an_in_progress_agent_response[Stops an in-progress Spotter agent response] for a given conversation session. The conversation session remains active after the response stops. + __Available on ThoughtSpot Cloud instances from 26.6.0.cl onwards.__ a| `POST /api/rest/2.0/ai/data-source-suggestions` [beta betaBackground]^Beta^ + -xref:spotter-agent-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. + +xref:spotter-agent-data-literacy-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__. a| `POST /api/rest/2.0/ai/relevant-questions/` [beta betaBackground]^Beta^ + -xref:spotter-agent-apis.adoc#_get_relevant_questions[Decomposes a user query] into relevant sub-questions. Guides users to explore data more deeply for a comprehensive analysis. + +xref:spotter-agent-data-literacy-apis.adoc#_get_relevant_questions[Decomposes a user query] into relevant sub-questions. Guides users to explore data more deeply for a comprehensive analysis. + __Available on ThoughtSpot Cloud instances from 10.13.0.cl onwards__. +a| `POST /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/share` [.version-badge.new]#New# + +xref:spotter-agent-sharing-apis.adoc#_share_a_conversation[Shares a saved Spotter conversation] with one or more users or groups. Use `grant` and `revoke` arrays to manage access. Shared conversations are `READ_ONLY`. + +__Available on ThoughtSpot Cloud instances from 26.9.0.cl onwards.__ + +a| `GET /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/get-shared-content` [.version-badge.new]#New# + +xref:spotter-agent-sharing-apis.adoc#_get_shared_content[Returns the shared content] of a Spotter conversation, including messages and associated answers. + +__Available on ThoughtSpot Cloud instances from 26.9.0.cl onwards.__ + +a| `GET /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/get-share-info` [.version-badge.new]#New# + +xref:spotter-agent-sharing-apis.adoc#_get_share_information[Returns sharing metadata] for a Spotter conversation — the list of principals it is shared with and whether the shared content is outdated. + +__Available on ThoughtSpot Cloud instances from 26.9.0.cl onwards.__ + a| `POST /api/rest/2.0/ai/agent/converse/sse` [.version-badge.deprecated]#Deprecated# + Legacy API endpoint for streaming responses, including tokens and visualizations, for a specific conversation context. __Deprecated in 26.5.0.cl__. @@ -70,1223 +82,19 @@ Legacy API endpoint to send natural language queries to a conversation session w __Deprecated in 26.5.0.cl__. |===== -== Create a conversation session with Spotter Agent - -The `/api/rest/2.0/ai/agent/conversation/create` API endpoint creates a new conversation session with Spotter Agent for a specific or multi-data context and returns a conversation ID. - -=== Request parameters -The request body must include the `metadata_context`. REST API clients must have at least view access to the data source objects specified in the API request to create a conversation session and use it for subsequent queries. - -[width="100%" cols="2,4"] -[options='header'] -|===== -|Form parameter| Description -|`metadata_context` a| Defines the data context for the conversation. - -* `type` + -Metadata context type. The context type is mandatory. Select one of the following values: - -** `AUTO_MODE` to allow Spotter Agent to automatically discover and select the most relevant datasets for users' queries. -** `DATA_SOURCE` to set a specific data source as the data context. You must specify `data_source_context` and data source IDs. + -To set a specific data source object, use `data_source_identifier`. + -To set multi-data context, use `data_source_identifiers`. -** `data_source` [.version-badge.deprecated]#Deprecated# + -This option is deprecated in 26.5.0.cl. ThoughtSpot recommends using the `DATA_SOURCE` with `data_source_context` and data source IDs instead. - -|`conversation_settings` a|__Optional__. Defines additional parameters for the conversation context. You can set any of the following attributes as needed: - -* `enable_contextual_change_analysis` + -__Boolean__. When enabled, Spotter analyzes how context changes over time, that is, comparing results from different queries. Enabled by default in 26.2.0.cl and later versions. -* `enable_natural_language_answer_generation` + -__Boolean__. Allows sending natural language queries to the conversation session. Enabled by default in 26.2.0.cl and later versions. -* `enable_reasoning` + -__Boolean__. Allows Spotter to use reasoning for deep analysis and precise responses. Enabled by default in 26.2.0.cl and later versions. -* `enable_save_chat` + -When set to `true`, adds the conversation to chat history. -|===== - -=== Example request - -With AUTO_MODE for metadata context:: - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/create' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "metadata_context": { - "type": "AUTO_MODE" - }, - "conversation_settings": { - "enable_save_chat": true - } -}' ----- - -For a single data source as the data context:: - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/create' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "metadata_context": { - "type": "DATA_SOURCE", - "data_source_context": { - "data_source_identifier": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" - } - }, - "conversation_settings": {} -}' ----- - -For multi-data source context:: - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/create' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "metadata_context": { - "type": "DATA_SOURCE", - "data_source_context": { - "data_source_identifiers": [ - "a1b2c3d4-e5f6-7890-abcd-ef1234567890", - "b2c3d4e5-f6a7-8901-bcde-f12345678901" - ] - } - }, - "conversation_settings": { - "enable_save_chat": true - } -}' ----- - -=== API response - -If the API request is successful, the API returns the conversation ID and identifier in the response body. - -[source,JSON] ----- -{ - "conversation_id": "wwHQ5j8O8dQC", - "conversation_identifier": "wwHQ5j8O8dQC" -} ----- - -* `conversation_identifier` + -Use this for all subsequent message calls. -* `conversation_id` [.version-badge.deprecated]#Deprecated# + -Returns the same value as `conversation_identifier`. - -== Send queries to a conversation session - -To send queries to an ongoing conversation session with the Spotter agent and receive a response synchronously, use the `/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send` API endpoint. - -This API operation requires the conversation ID obtained from the conversation creation API endpoint (`/api/rest/2.0/ai/agent/conversation/create`). The user making the API request must have access to the conversation session. The API request body must include at least one message in natural language format. - -=== Request parameters - -[width="100%" cols="2,2,4"] -[options='header'] -|===== -|Parameter|Type| Description -|`conversation_identifier`|Path parameter|__String__. Required. Specify the conversation ID received from the xref:spotter-agent-apis.adoc#_create_a_conversation_session_with_spotter_agent[POST /api/rest/2.0/ai/agent/conversation/create] API call. -|`messages`|Form parameter|_Array of strings_. Required. Specify at least one query in natural language. For example, `total sales of jackets last month`. -|===== - - -//// -|`settings` |__Optional__. Defines additional parameters for the conversation context. You can set any of the following attributes as needed: - -* `enable_contextual_change_analysis` + -__Boolean__. When enabled, Spotter analyzes how the context changes over time, that is comparing results from different queries. -* `enable_natural_language_answer_generation` + -__Boolean__. Allows sending natural language queries to the conversation session. -* `enable_reasoning` + -__Boolean__. Allows Spotter to use reasoning for deep analysis and precise responses. -//// - -=== Request and response examples - -The following example sends a data comparison query to a conversation session. The conversation ID is specified in the request URL as a path parameter. - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "messages": [ - "Sales in 2025 vs 2024" - ] -}' ----- - -If the request is successful, the API returns an array of objects in the response. The messages in the API response include the following parts: - -[source,JSON] ----- -[ - { - "type": "text", - "text": "\n\nI'll compare sales between 2025 and 2024. First, let me get the dataset context.", - "metadata": {}, - "internal": {}, - "agent_context": "" - }, - { - "type": "text", - "text": "```json\n{\"dataset_name\":\"(Sample) Retail - Apparel\",\"columns\":[{\"name\":\"sales\",\"type\":\"MEASURE\"},{\"name\":\"date\",\"type\":\"ATTRIBUTE\"}]}\n```", - "metadata": {}, - "internal": {}, - "agent_context": "" - }, - { - "type": "answer", - "title": "Compare total sales for 2025 vs 2024", - "description": "", - "session_id": "842bb67a-e08e-4861-97e8-8db9538db51d", - "gen_no": 2, - "sage_query": "[sales] [date] = '2025' vs [date] = '2024'", - "tml_tokens": ["[sales]", "[date] = '2025' vs [date] = '2024'"], - "formulas": [], - "parameters": [], - "subqueries": [], - "viz_suggestion": "CAEQIBomEiQ2NjE5NzI0Yy1kMjVlLTU4MDItOWNjOC1jNDA3MWY3OWY5MzAoATIA", - "metadata": { - "output": "", - "worksheet_id": "cd252e5c-b552-49a8-821d-3eadaa049cca", - "chart_type": "KPI", - "interrupted": false, - "data_awareness_enabled": true - }, - "internal": {} - }, - { - "type": "text", - "text": "\n\nThe visualization shows year-over-year comparison. You can identify growth or decline trends.", - "metadata": {}, - "internal": {}, - "agent_context": "" - } -] ----- - -The following example sends a follow-up question to the same conversation session. - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "messages": [ - "Now break that down by product category" - ] -}' ----- - -If the request is successful, the agent returns the response for the follow-up question: - -[source,JSON] ----- -[{ - "type": "text", - "text": "I'll add product category to the comparison.", - "metadata": {}, - "internal": {}, - "agent_context": "" - }, - { - "type": "answer", - "title": "Sales by Product Category: 2025 vs 2024", - "session_id": "9abc1234-0000-0000-0000-000000000005", - "gen_no": 3, - "sage_query": "[sales] [product category] [date] = '2025' vs [date] = '2024'", - "tml_tokens": ["[sales]", "[product category]", "[date] = '2025' vs [date] = '2024'"], - "formulas": [], - "parameters": [], - "subqueries": [], - "viz_suggestion": "", - "metadata": { - "chart_type": "BAR", - "worksheet_id": "cd252e5c-b552-49a8-821d-3eadaa049cca" - }, - "internal": {} - }] ----- - -In each response, the agent returns the following information: - -* `type` + -Type of the message, such as text, answer, or error. -* `text` + -Response message generated for the query. -* `metadata` + -Additional information based on the message type. For example, answer metadata, chart type, or the data source ID. -* `tml_tokens` + -Query string broken down as TML tokens. - -In case of errors, the response returns the error details: - -[source,JSON] ----- -[{ - "type": "error", - "message": "The conversation session has expired. Please create a new conversation.", - "code": "SESSION_EXPIRED" -}] ----- - - - -//// -The following example shows the response text contents for the `answer` message type. - -[source,JSON] ----- -[ - { - "id": "r24X7D99SROD", - "type": "answer", - "group_id": "o8dQ9SAWdtrL", - "metadata": { - "sage_query": "[sales] [item type] = [item type].'jackets'", - "session_id": "b321b404-cbf1-4905-9b0c-b93ad4eedf89", - "gen_no": 1, - "transaction_id": "6874259d-13b1-478c-83cb-b3ed52628850", - "generation_number": 1, - "warning_details": null, - "ambiguous_phrases": null, - "query_intent": null, - "assumptions": "You want to see the total sales amount for jackets item type.", - "tml_phrases": [ - "[sales]", - "[item type] = [item type].'jackets'" - ], - "cached": false, - "sub_queries": null, - "title": "Net sales of Jackets", - "worksheet_id": "cd252e5c-b552-49a8-821d-3eadaa049cca" - }, - "title": "Net sales of Jackets" - } -] ----- - -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. - - -* The tokens and TML phrases returned in the response can be used as inputs for the search data API call to get an Answer. -//// - -== Send a query to agent and get streaming responses - -To send queries to an ongoing conversation session with Spotter agent and receive streaming responses, use the `/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send/stream` API endpoint. This API endpoint uses the SSE protocol to deliver data incrementally in real time, rather than waiting for the entire response to be generated before sending it to the client. - -The `/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send/stream` API can be used as an integrated tool for real-time streaming of conversational interactions between agents and the ThoughtSpot backend. - -=== Request parameters - -[width="100%" cols="2,4"] -[options='header'] -|===== -|Parameter| Description -|`conversation_identifier` |__String__. Specify the conversation ID received from the xref:spotter-agent-apis.adoc#_create_a_conversation_session_with_spotter_agent[POST /api/rest/2.0/ai/agent/conversation/create] API call. -|`messages`|_Array of strings_. Include at least one natural language query. For example, `Sales data for Jackets`, `Top performing products in the west coast`. -|===== - -=== Example request - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send/stream' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "conversation_identifier": "h2I_pTGaRQof", - "messages": [ - "Net sales of Jackets" - ] -}' ----- - -=== API response - -If the API request is successful, the response includes a stream of events, each containing a partial or complete message from the AI agent, rather than a single JSON object. - -Each event is a simple text-based message in a specific format, `data: \n\n`; `\n\n` means that each message sent from the server to the client is prefixed with the `data:` keyword, followed by the actual payload (``), and ends with two newline characters (`\n\n`). - -The API uses this format so that the clients can reconstruct the AI-generated response as it streams in, chunk by chunk, and show the responses in real-time. In agentic workflows, the receiving client or agent listens to the SSE stream, parses each event, and assembles the full response for its users. - -==== Example response -If the request is valid, the API returns SSE streams. Each line has the form `data: [{"type": "...", ...}]`, a JSON array of event objects. - -[source,JSON] ----- -data: [{"type":"ack","node_id":"aGxzcFVrtom8"}] - -data: [{"type":"conv_title","title":"Sales 2025 vs 2024","conv_id":"-XIi04l5rrof"}] - -data: [{"type":"notification","group_id":"cDEsAQbSnd3J","metadata":{"type":"thinking","tool_title":"Analyzing Sales Performance: 2025 vs 2024"},"code":"TOOL_CALL_NOTIFICATION"}] - -data: [{"id":"mNAdvy-NK2l6","type":"text-chunk","group_id":"cDEsAQbSnd3J","metadata":{"format":"markdown","type":"thinking"},"content":"\n\nI need to compare sales performance between 2025 and 2024."}] - -data: [{"type":"notification","group_id":"m1MTvttEUa7o","code":"nls_start"}] - -data: [{"id":"hxWMDP-pgR3B","type":"answer","group_id":"m1MTvttEUa7o","metadata":{"sage_query":"[sales] [date] = '2025' vs [date] = '2024'","session_id":"431adcf9-1328-4d8c-81a1-0faa7fa37ba6","title":"Compare sales for 2025 vs 2024"},"title":"Compare sales for 2025 vs 2024"}] - -data: [{"type":"notification","code":"FINAL_RESPONSE_NOTIFICATION"}] ----- -For the complete response in one payload, use the xref:spotter-agent-apis.adoc#_send_queries_to_a_conversation_session[`/send` endpoint] instead. - -//// -[source,] ----- -data: [{"type": "ack", "node_id": "BRxCtJ-aGt8l"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": "I"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " understand"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " you're"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " interested"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " in"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " the"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " net"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " sales"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " of"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " Jackets"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": "."}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " I'll"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " retrieve"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " the"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " relevant"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " data"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " for"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " you"}] - -data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": "."}] - -data: [{"type": "notification", "group_id": "o8dQ9SAWdtrL", "metadata": {"title": "Net sales of Jackets"}, "code": "nls_start"}] - -data: [{"type": "notification", "group_id": "o8dQ9SAWdtrL", "code": "QH", "message": "Fetching Worksheet Data"}] - -data: [{"type": "notification", "group_id": "o8dQ9SAWdtrL", "code": "TML_GEN", "message": "Translating your query with the Reasoning Engine"}] - -data: [{"type": "notification", "group_id": "o8dQ9SAWdtrL", "code": "ANSWER_GEN", "message": "Verifying results with the Trust Layer"}] - -data: [{"id": "r24X7D99SROD", "type": "answer", "group_id": "o8dQ9SAWdtrL", "metadata": {"sage_query": "[sales] [item type] = [item type].'jackets'", "session_id": "b321b404-cbf1-4905-9b0c-b93ad4eedf89", "gen_no": 1, "transaction_id": "6874259d-13b1-478c-83cb-b3ed52628850", "generation_number": 1, "warning_details": null, "ambiguous_phrases": null, "query_intent": null, "assumptions": "You want to see the total sales amount for jackets item type.", "tml_phrases": ["[sales]", "[item type] = [item type].'jackets'"], "cached": false, "sub_queries": null, "title": "Net sales of Jackets", "worksheet_id": "cd252e5c-b552-49a8-821d-3eadaa049cca"}, "title": "Net sales of Jackets"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "The"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " net"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " sales"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " for"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " Jackets"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " have"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " been"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " visual"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "ized"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " for"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " you"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "."}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " This"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " analysis"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " specifically"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " filtered"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " for"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " the"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " item"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " type"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "jackets"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "\""}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " and"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " calculated"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " the"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " total"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " sales"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " amount"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " associated"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " with"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " those"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " products"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ".\n\n"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "**"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "Summary"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " &"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " Insights"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ":"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "**\n"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "-"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " The"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " visualization"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " shows"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " the"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " total"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " net"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " sales"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " for"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " all"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " jacket"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " transactions"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " in"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " your"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " apparel"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " dataset"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ".\n"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "-"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " The"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " calculation"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " uses"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " only"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " sales"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " amounts"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " where"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " the"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " item"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " type"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " is"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " \""}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "J"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "ackets"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ".\"\n"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "-"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " This"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " information"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " is"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " useful"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " for"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " understanding"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " the"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " revenue"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " contribution"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " of"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " jackets"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " within"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " your"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " product"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " mix"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ".\n\n"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "If"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " you'd"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " like"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " to"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " see"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " a"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " breakdown"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " by"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " region"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ","}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " state"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ","}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " time"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " period"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ","}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " or"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " compare"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " jacket"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " sales"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " to"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " other"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " product"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " types"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ","}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " please"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " let"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " me"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " know"}] - -data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "!"}] ----- -//// - -==== SSE event types -The SSE event types streamed in the API response include: - -* `ack` + -Confirms receipt of the request. For example, the type in the first message `data: [{"type": "ack", "node_id": "BRxCtJ-aGt8l"}]`, which indicates that the server has received the client's request and is acknowledging it. -* `conv_title` + -A conversation title (`title`, `conv_id`). -* `notification` + -Progress or status update (`group_id`, `metadata`, `code`). For example, `TOOL_CALL_NOTIFICATION`, `nls_start`, `FINAL_RESPONSE_NOTIFICATION`. -* `type` + -Type can be `thinking`, `text`. -* `text` + -Complete text block in markdown format. -* `text-chunk` + -Text fragments in incremental streaming, often in markdown (`id`, `group_id`, `metadata` with `format`) -* `content` + -The actual text content sent incrementally. For example, `"I"`, `"understand"`, `"you're"`, `"interested"`, `"in"`, `"the"`, `"net"`, `"sales"`, and so on. -* `text` + -Full text block with same structure as text-chunk. -* `answer` + -Structured answer with metadata (`id`, `group_id`, `metadata` with `sage_query`, `session_id`, `title` and more) -* `error` + -In case of failures. -* `*-interrupt` + -If the generation was stopped mid-stream. -* `group_id` + -Groups related chunks together. - -For more information and examples, see xref:spotter-agent-apis.adoc#_sse_event_payload_reference[SSE event payload reference]. - -=== Thinking versus output events -Spotter responses have two phases: - -* A *thinking phase*, where the AI reasons through the query and calls internal tools, followed by an *output phase* containing the final response delivered to the user. + - -Events in the thinking phase carry `"metadata": { "type": "thinking" }`. All other events are final output. - -Every event includes a `group_id`. Events sharing the same `group_id` belong together. During the thinking phase, each tool call gets its own `group_id`. A `FINAL_RESPONSE_NOTIFICATION` notification marks the boundary between the thinking and output phases. - -[listing] ----- -THINKING PHASE -─────────────────────────────────────────────────────────── -ack - -┌─ group_id: g1 ── Tool Call 1 ("Searching data") ─────────┐ -│ notification (thinking, TOOL_CALL_NOTIFICATION) │ -│ text-chunk (thinking) │ -│ answer (thinking) │ -└──────────────────────────────────────────────────────────┘ - -┌─ group_id: g2 ── Tool Call 2 ("Running code") ───────────┐ -│ notification (thinking, TOOL_CALL_NOTIFICATION) │ -│ text-chunk (thinking) │ -│ text-chunk (thinking) │ -└──────────────────────────────────────────────────────────┘ - -notification (FINAL_RESPONSE_NOTIFICATION) ←── boundary -──────────────────────────────────────────────────────────── - -OUTPUT PHASE -──────────────────────────────────────────────────────────── -┌─ group_id: g3 ────────────────────────────────────────────┐ -│ text "Here are the results:" │ -│ answer (final visualization) │ -└───────────────────────────────────────────────────────────┘ -[stream closes] ----- - -==== Notification codes reference - -[width="100%" cols="2,4"] -[options='header'] -|===== -|Code| When it appears -|`QH`|Query handling started -|`TML_GEN` / `TML_GEN_RETRY`|Generating or retrying TML -|`ANSWER_GEN`|Generating an answer -|`IDENTIFYING_ATTRIBUTES`|Identifying data attributes -|`PERFORMING_CHANGE_ANALYSIS`|Running change analysis -|`PERFORMING_FORECASTING_ANALYSIS`|Running forecasting -|`SUMMARIZING_RESULTS`|Summarizing results -|`TOOL_CALL_NOTIFICATION`|Tool invocation (during thinking phase) -|`FINAL_RESPONSE_NOTIFICATION`|Marks the transition from thinking to output -|`search_datasets_start` / `search_datasets_end`|Data source discovery in progress or complete -|`approval_required`|An external tool requires user permission before proceeding -|===== - -=== SSE event payload reference - -==== ack - -[source,JSON] ----- -data: { - "type": "ack", - "group_id": "a1b2c3", - "id": "evt-001", - "node_id": "resp-node-abc" -} ----- - -==== notification (thinking — tool call) - -[source,JSON] ----- -data: { - "type": "notification", - "group_id": "g1", - "id": "evt-002", - "code": "TOOL_CALL_NOTIFICATION", - "message": "Searching for relevant data", - "metadata": { - "type": "thinking", - "tool_title": "Searching sales data", - "tool_code": "RUNNING_CODE_EXECUTION", - "tool_name": "code_interpreter" - } -} ----- - -==== notification (thinking - external tool with MCP integration) - -[source,JSON] ----- -data: { - "type": "notification", - "group_id": "g2", - "id": "evt-003", - "code": "TOOL_CALL_NOTIFICATION", - "message": "Querying Salesforce", - "metadata": { - "type": "thinking", - "tool_title": "Salesforce: Get Opportunities", - "tool_name": "get_opportunities", - "integration_id": "int-sf-123", - "integration_name": "Salesforce" - } -} ----- - -==== notification (approval required) -Sent when an external MCP tool requires explicit user permission before proceeding. Your application should prompt the user to approve or deny the action before continuing. - -[source,JSON] ----- -data: { - "type": "notification", - "group_id": "g2", - "id": "evt-005", - "code": "approval_required", - "metadata": { - "request_id": "perm-req-789", - "integration_id": "int-sf-123", - "integration_name": "Salesforce", - "tool_name": "get_opportunities", - "annotated_title": "Access Salesforce Opportunities" - } -} ----- - -==== notification (FINAL_RESPONSE_NOTIFICATION) - -[source,JSON] ----- -data: { - "type": "notification", - "group_id": "g1", - "id": "evt-004", - "code": "FINAL_RESPONSE_NOTIFICATION", - "message": "" -} ----- - -==== text - -[source,JSON] ----- -data: { - "type": "text", - "group_id": "g3", - "id": "evt-007", - "content": "Here is the total revenue breakdown by region for Q4 2025:\n\n- **North America:** $4.2M\n- **EMEA:** $2.8M\n- **APAC:** $1.5M" -} ----- - -==== text-chunk -Multiple chunks sharing the same `id` should be appended together to reconstruct the full text item. - -[source,JSON] ----- -data: { "type": "text-chunk", "group_id": "g3", "id": "evt-009", "content": "Based on the analysis, " } -data: { "type": "text-chunk", "group_id": "g3", "id": "evt-009", "content": "revenue grew 12% quarter-over-quarter." } ----- - -==== answer -When an `answer` event is received, the `session_id` and `gen_no` fields are returned. You can export the visualization data using the Export Answer Report API to process the results. This allows users to download the answer as a PDF, PNG, CSV, or XLSX file. - -[source,JSON] ----- -data: { - "type": "answer", - "group_id": "g3", - "id": "evt-010", - "title": "Revenue by Region Q4 2025", - "metadata": { - "session_id": "sess-abc-123", - "gen_no": 1, - "transaction_id": "txn-456", - "worksheet_id": "ws-def-789", - "cached": false, - "is_hidden": false - } -} ----- - -==== search_datasets -Emitted as a start/end pair during Auto mode data source discovery. - - -[source,JSON] ----- -data: { "type": "search_datasets", "group_id": "g0", "id": "evt-012", "code": "search_datasets_start", "metadata": {} } - -data: { - "type": "search_datasets", - "group_id": "g0", - "id": "evt-013", - "code": "search_datasets_end", - "metadata": { - "data_sources": [ - { "worksheet_id": "ws-1", "worksheet_name": "Sales Data", "confidence": "high", "reasoning": "Contains revenue columns" }, - { "worksheet_id": "ws-2", "worksheet_name": "Marketing Data", "confidence": "low", "reasoning": "No revenue columns" } - ], - "auto_selected": { "worksheet_id": "ws-1", "worksheet_name": "Sales Data", "confidence": "high", "reasoning": "Best match" } - } -} ----- -==== file - -[source,JSON] ----- -data: { - "type": "file", - "group_id": "g3", - "id": "evt-014", - "files": [ - { "ts_file_id": "file-abc-001", "display_name": "quarterly_report.csv", "file_type": "csv", "created_at": "2025-11-15T10:30:00Z" }, - { "ts_file_id": "file-abc-002", "display_name": "chart.png", "file_type": "png", "created_at": "2025-11-15T10:30:01Z" } - ], - "metadata": { "conv_id": "conv-123" } -} ----- -==== conv_title - -[source,JSON] ----- -data: { - "type": "conv_title", - "group_id": "g0", - "id": "evt-015", - "title": "Revenue Analysis Q4 2025", - "conv_id": "conv-123" -} ----- - -==== error - -[source,JSON] ----- -data: { - "type": "error", - "group_id": "g3", - "id": "evt-016", - "code": "RATE_LIMIT_EXCEEDED", - "message": "Too many requests", - "display_message": "You've exceeded the rate limit. Please try again in a few minutes." -} ----- -==== agent-interrupt - -[source,JSON] ----- -Sent when generation is stopped mid-stream. -data: { - "type": "notification", - "group_id": "g3", - "id": "evt-017", - "code": "agent-interrupt", - "message": "Generation stopped" -} ----- - -[#_stop_an_in_progress_agent_response] -== Stop an in-progress agent response - -The `/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/stop-response` API endpoint stops a Spotter agent response that is currently in progress for a given conversation session. - -Use this endpoint when you want to cancel a long-running Spotter response before it completes. The conversation session remains active after you stop a response, so you can send a new query to the same session immediately. - -=== Request parameters - -[width="100%", cols="2,2,4"] -[options='header'] -|===== -|Parameter|Type| Description -|`conversation_identifier`|Path parameter|__String__. Required. The identifier of the active conversation session. Use the value returned by the xref:spotter-agent-apis.adoc#_create_a_conversation_session_with_spotter_agent[create conversation] API endpoint. -|===== - -This endpoint does not require a request body. - -=== Example request - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/stop-response' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' ----- - -=== Example response - -If the API request is successful, ThoughtSpot stops the in-progress response and returns a 204 response code. - -If the conversation session is not found or has expired, the API returns an error: - -[source,JSON] ----- -{ - "error_code": "CONVERSATION_NOT_FOUND", - "message": "The specified conversation session does not exist or has expired." -} ----- - -[#process_results] -== Process results generated from a conversation session -To export or download the Answer data generated by the Spotter APIs, use the xref:data-report-v2-api.adoc#exportSpotterData[Answer report] API. - -The `session_id` and `gen_no` values from the `answer` event metadata are required to identify the answer to export. - -NOTE: Requires at least view access to the Answer. - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/answer' \ - -H 'Authorization: Bearer {Bearer_token}' \ - -H 'Accept: application/octet-stream' \ - -H 'Content-Type: application/json' \ - --data-raw '{ - "session_identifier": "sess-abc-123", - "generation_number": 1, - "file_format": "CSV" -}' ----- -The `file_format` parameter accepts `PDF`, `PNG`, `CSV`, or `XLSX`. - -[NOTE] -==== -Using tokens generated by the Spotter API in a xref:data-report-v2-api.adoc#_search_data_api[Search Data API] request can return invalid column errors, because these tokens may reference formulas or columns not present in the data model. Instead, use the xref:data-report-v2-api.adoc#exportSpotterData[Answer report] API and include the session ID and generation number obtained from the Spotter API in your API request to retrieve the data. -==== - - -== Data literacy and query assistance -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 - -The `POST /api/rest/2.0/ai/data-source-suggestions` API provides relevant data source recommendations for a user-submitted natural language query. To use this API, you must have at least view access to the underlying metadata object referenced in the response. - -==== Request parameters - -[width="100%" cols="2,4"] -[options='header'] -|==== -|Parameter| Description -|`metadata_context` a| Required. Specify one of the following attributes to set the metadata context: - -* `data_source_identifiers` + -__Array of strings__. IDs of the data source object such as Models. -* `answer_identifiers` + -__Array of strings__. GUIDs of the Answer objects that you want to use as metadata. -* `conversation_identifier` + -__String__. ID of the conversation session. -* `liveboard_identifiers` + -__Array of strings__. GUIDs of the Liveboards that you want to use as metadata. - -| `query` |__String__. Required parameter. Specify the query string that needs to be decomposed into smaller, analytical sub-questions. -|`limit_relevant_questions` + -__Optional__ | __Integer__. Sets a limit on the number of sub-questions to return in the response. Default is 5. -|`bypass_cache` + -__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 - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/data-source-suggestions' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "metadata_context": { - "data_source_identifiers": [ - "cd252e5c-b552-49a8-821d-3eadaa049cca" - ] - }, - "query": "Net sales of Jackets in west coast", - "limit_relevant_questions": 3 -}' ----- - -==== API response -If the API request is successful, ThoughtSpot returns a ranked list of data sources, each annotated with relevant reasoning. - -[source,JSON] ----- -{ - "relevant_questions": [ - { - "query": "What is the trend of sales by type over time?", - "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", - "data_source_name": "(Sample) Retail - Apparel" - }, - { - "query": "Sales by item", - "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", - "data_source_name": "(Sample) Retail - Apparel" - }, - { - "query": "Sales across regions", - "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", - "data_source_name": "(Sample) Retail - Apparel" - } - ] -} ----- - -The returned results include metadata such as: - -* `confidence` + -A float indicating the Model's confidence in the relevance of each recommendation. -* `details` + -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. - -During agentic interactions, this API can be used as an integrated tool to decompose user queries and suggest relevant questions for a specific data context. REST clients can also call this API directly to fetch relevant questions via a `POST` request. - -==== Request parameters - -[width="100%" cols="2,4"] -[options='header'] -|===== -|Parameter| Description -|`metadata_context` a| Required. Specify one of the following attributes to set the metadata context: - -* `data_source_identifiers` + -__Array of strings__. IDs of the data source object such as Models. -* `answer_identifiers` + -__Array of strings__. GUIDs of the Answer objects that you want to use as metadata. -* `conversation_identifier` + -__String__. ID of the conversation session. -* `liveboard_identifiers` + -__Array of strings__. GUIDs of the Liveboards that you want to use as metadata. - -| `query` |__String__. Required parameter. Specify the query string that needs to be decomposed into smaller, analytical sub-questions. -|`limit_relevant_questions` + -__Optional__ | __Integer__. Sets a limit on the number of sub-questions to return in the response. Default is 5. -|`bypass_cache` + -__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: - -* `instructions` + -__Array of strings__. Custom user instructions to influence how the AI interprets and processes the query. -* `content` + -__Array of strings__. Additional input such as raw text or CSV-formatted data to enhance context and answer quality. -|===== - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/relevant-questions/' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "metadata_context": { - "data_source_identifiers": [ - "cd252e5c-b552-49a8-821d-3eadaa049cca" - ] - }, - "query": "Net sales of Jackets in west coast", - "limit_relevant_questions": 3 -}' ----- - -==== Example response -If the request is successful, the API returns a set of questions related to the query and metadata context in the `relevant_questions` array. Each object in the `relevant_questions` array contains the following fields: - -* `query` + -A string containing the natural language (NL) sub-question. -* `data_source_identifier` + -GUID of the data source object. -* `data_source_name` + -Name of the associated data source object. - -[source,JSON] ----- -{ - "relevant_questions": [ - { - "query": "What is the trend of sales by type over time?", - "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", - "data_source_name": "(Sample) Retail - Apparel" - }, - { - "query": "Sales by item", - "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", - "data_source_name": "(Sample) Retail - Apparel" - }, - { - "query": "Sales across regions", - "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", - "data_source_name": "(Sample) Retail - Apparel" - } - ] -} ----- - == Additional resources +* xref:spotter-agent-conversation-apis.adoc[Spotter agent conversation APIs] + +Create conversation sessions, send synchronous queries, and stop in-progress responses. +* xref:spotter-agent-streaming-apis.adoc[Spotter agent streaming APIs] + +Send queries and receive real-time Server-Sent Events (SSE) responses from the Spotter agent. +* xref:spotter-agent-process-results-apis.adoc[Process Spotter agent conversation results] + +Export or download Answers generated by a Spotter agent conversation session. +* xref:spotter-agent-data-literacy-apis.adoc[Spotter agent data literacy APIs] + +Get data source suggestions and decompose a user query into relevant sub-questions. +* xref:spotter-agent-sharing-apis.adoc[Spotter agent conversation sharing APIs] + +Share saved Spotter conversations with other users and groups. +* xref:spotter-agent-conversation-mgmt-apis.adoc[APIs for managing saved conversations] + +Retrieve, update, and delete saved Spotter 3 conversations and their messages. * Visit the +++REST API v2.0 Playground+++ to view the API endpoints and verify the request and response workflows. * For information about MCP tools, see xref:mcp-integration.adoc[MCP server integration]. diff --git a/modules/ROOT/pages/spotter-agent-conversation-apis.adoc b/modules/ROOT/pages/spotter-agent-conversation-apis.adoc new file mode 100644 index 000000000..1e094a6aa --- /dev/null +++ b/modules/ROOT/pages/spotter-agent-conversation-apis.adoc @@ -0,0 +1,385 @@ += Spotter agent conversation APIs +:toc: true +:toclevels: 2 + +:page-title: Spotter agent conversation APIs +:page-pageid: spotter-agent-conversation-apis +:page-description: Use the Spotter agent conversation REST APIs to create conversation sessions, send natural language queries, and stop in-progress responses. + +ThoughtSpot's Spotter agent conversation APIs allow you to create a conversation session with the Spotter agent, send natural language queries to it, and stop an in-progress response. + +For information about receiving responses as a real-time event stream, see xref:spotter-agent-streaming-apis.adoc[Spotter agent streaming APIs]. For information about exporting Answers generated by a conversation, see xref:spotter-agent-process-results-apis.adoc[Process Spotter agent conversation results]. For information about the data source and question suggestion APIs, see xref:spotter-agent-data-literacy-apis.adoc[Spotter agent data literacy APIs]. For information about sharing saved conversations, see xref:spotter-agent-sharing-apis.adoc[Spotter agent conversation sharing APIs]. + +== Create a conversation session with Spotter Agent + +The `/api/rest/2.0/ai/agent/conversation/create` API endpoint creates a new conversation session with Spotter Agent for a specific or multi-data context and returns a conversation ID. + +=== Request parameters +The request body must include the `metadata_context`. REST API clients must have at least view access to the data source objects specified in the API request to create a conversation session and use it for subsequent queries. + +[width="100%" cols="2,4"] +[options='header'] +|===== +|Form parameter| Description +|`metadata_context` a| Defines the data context for the conversation. + +* `type` + +Metadata context type. The context type is mandatory. Select one of the following values: + +** `AUTO_MODE` to allow Spotter Agent to automatically discover and select the most relevant datasets for users' queries. +** `DATA_SOURCE` to set a specific data source as the data context. You must specify `data_source_context` and data source IDs. + +To set a specific data source object, use `data_source_identifier`. + +To set multi-data context, use `data_source_identifiers`. +** `data_source` [.version-badge.deprecated]#Deprecated# + +This option is deprecated in 26.5.0.cl. ThoughtSpot recommends using the `DATA_SOURCE` with `data_source_context` and data source IDs instead. + +|`conversation_settings` a|__Optional__. Defines additional parameters for the conversation context. You can set any of the following attributes as needed: + +* `enable_contextual_change_analysis` + +__Boolean__. When enabled, Spotter analyzes how context changes over time, that is, comparing results from different queries. Enabled by default in 26.2.0.cl and later versions. +* `enable_natural_language_answer_generation` + +__Boolean__. Allows sending natural language queries to the conversation session. Enabled by default in 26.2.0.cl and later versions. +* `enable_reasoning` + +__Boolean__. Allows Spotter to use reasoning for deep analysis and precise responses. Enabled by default in 26.2.0.cl and later versions. +* `enable_save_chat` + +When set to `true`, adds the conversation to chat history. +|===== + +=== Example request + +With AUTO_MODE for metadata context:: + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/create' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "metadata_context": { + "type": "AUTO_MODE" + }, + "conversation_settings": { + "enable_save_chat": true + } +}' +---- + +For a single data source as the data context:: + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/create' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "metadata_context": { + "type": "DATA_SOURCE", + "data_source_context": { + "data_source_identifier": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" + } + }, + "conversation_settings": {} +}' +---- + +For multi-data source context:: + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/create' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "metadata_context": { + "type": "DATA_SOURCE", + "data_source_context": { + "data_source_identifiers": [ + "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "b2c3d4e5-f6a7-8901-bcde-f12345678901" + ] + } + }, + "conversation_settings": { + "enable_save_chat": true + } +}' +---- + +=== API response + +If the API request is successful, the API returns the conversation ID and identifier in the response body. + +[source,JSON] +---- +{ + "conversation_id": "wwHQ5j8O8dQC", + "conversation_identifier": "wwHQ5j8O8dQC" +} +---- + +* `conversation_identifier` + +Use this for all subsequent message calls. +* `conversation_id` [.version-badge.deprecated]#Deprecated# + +Returns the same value as `conversation_identifier`. + +== Send queries to a conversation session + +To send queries to an ongoing conversation session with the Spotter agent and receive a response synchronously, use the `/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send` API endpoint. + +This API operation requires the conversation ID obtained from the conversation creation API endpoint (`/api/rest/2.0/ai/agent/conversation/create`). The user making the API request must have access to the conversation session. The API request body must include at least one message in natural language format. + +=== Request parameters + +[width="100%" cols="2,2,4"] +[options='header'] +|===== +|Parameter|Type| Description +|`conversation_identifier`|Path parameter|__String__. Required. Specify the conversation ID received from the xref:spotter-agent-conversation-apis.adoc#_create_a_conversation_session_with_spotter_agent[POST /api/rest/2.0/ai/agent/conversation/create] API call. +|`messages`|Form parameter|_Array of strings_. Required. Specify at least one query in natural language. For example, `total sales of jackets last month`. +|===== + + +//// +|`settings` |__Optional__. Defines additional parameters for the conversation context. You can set any of the following attributes as needed: + +* `enable_contextual_change_analysis` + +__Boolean__. When enabled, Spotter analyzes how the context changes over time, that is comparing results from different queries. +* `enable_natural_language_answer_generation` + +__Boolean__. Allows sending natural language queries to the conversation session. +* `enable_reasoning` + +__Boolean__. Allows Spotter to use reasoning for deep analysis and precise responses. +//// + +=== Request and response examples + +The following example sends a data comparison query to a conversation session. The conversation ID is specified in the request URL as a path parameter. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "messages": [ + "Sales in 2025 vs 2024" + ] +}' +---- + +If the request is successful, the API returns an array of objects in the response. The messages in the API response include the following parts: + +[source,JSON] +---- +[ + { + "type": "text", + "text": "\n\nI'll compare sales between 2025 and 2024. First, let me get the dataset context.", + "metadata": {}, + "internal": {}, + "agent_context": "" + }, + { + "type": "text", + "text": "```json\n{\"dataset_name\":\"(Sample) Retail - Apparel\",\"columns\":[{\"name\":\"sales\",\"type\":\"MEASURE\"},{\"name\":\"date\",\"type\":\"ATTRIBUTE\"}]}\n```", + "metadata": {}, + "internal": {}, + "agent_context": "" + }, + { + "type": "answer", + "title": "Compare total sales for 2025 vs 2024", + "description": "", + "session_id": "842bb67a-e08e-4861-97e8-8db9538db51d", + "gen_no": 2, + "sage_query": "[sales] [date] = '2025' vs [date] = '2024'", + "tml_tokens": ["[sales]", "[date] = '2025' vs [date] = '2024'"], + "formulas": [], + "parameters": [], + "subqueries": [], + "viz_suggestion": "CAEQIBomEiQ2NjE5NzI0Yy1kMjVlLTU4MDItOWNjOC1jNDA3MWY3OWY5MzAoATIA", + "metadata": { + "output": "", + "worksheet_id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "chart_type": "KPI", + "interrupted": false, + "data_awareness_enabled": true + }, + "internal": {} + }, + { + "type": "text", + "text": "\n\nThe visualization shows year-over-year comparison. You can identify growth or decline trends.", + "metadata": {}, + "internal": {}, + "agent_context": "" + } +] +---- + +The following example sends a follow-up question to the same conversation session. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "messages": [ + "Now break that down by product category" + ] +}' +---- + +If the request is successful, the agent returns the response for the follow-up question: + +[source,JSON] +---- +[{ + "type": "text", + "text": "I'll add product category to the comparison.", + "metadata": {}, + "internal": {}, + "agent_context": "" + }, + { + "type": "answer", + "title": "Sales by Product Category: 2025 vs 2024", + "session_id": "9abc1234-0000-0000-0000-000000000005", + "gen_no": 3, + "sage_query": "[sales] [product category] [date] = '2025' vs [date] = '2024'", + "tml_tokens": ["[sales]", "[product category]", "[date] = '2025' vs [date] = '2024'"], + "formulas": [], + "parameters": [], + "subqueries": [], + "viz_suggestion": "", + "metadata": { + "chart_type": "BAR", + "worksheet_id": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "internal": {} + }] +---- + +In each response, the agent returns the following information: + +* `type` + +Type of the message, such as text, answer, or error. +* `text` + +Response message generated for the query. +* `metadata` + +Additional information based on the message type. For example, answer metadata, chart type, or the data source ID. +* `tml_tokens` + +Query string broken down as TML tokens. + +In case of errors, the response returns the error details: + +[source,JSON] +---- +[{ + "type": "error", + "message": "The conversation session has expired. Please create a new conversation.", + "code": "SESSION_EXPIRED" +}] +---- + + + +//// +The following example shows the response text contents for the `answer` message type. + +[source,JSON] +---- +[ + { + "id": "r24X7D99SROD", + "type": "answer", + "group_id": "o8dQ9SAWdtrL", + "metadata": { + "sage_query": "[sales] [item type] = [item type].'jackets'", + "session_id": "b321b404-cbf1-4905-9b0c-b93ad4eedf89", + "gen_no": 1, + "transaction_id": "6874259d-13b1-478c-83cb-b3ed52628850", + "generation_number": 1, + "warning_details": null, + "ambiguous_phrases": null, + "query_intent": null, + "assumptions": "You want to see the total sales amount for jackets item type.", + "tml_phrases": [ + "[sales]", + "[item type] = [item type].'jackets'" + ], + "cached": false, + "sub_queries": null, + "title": "Net sales of Jackets", + "worksheet_id": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "title": "Net sales of Jackets" + } +] +---- + +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. + + +* The tokens and TML phrases returned in the response can be used as inputs for the search data API call to get an Answer. +//// + +[#_stop_an_in_progress_agent_response] +== Stop an in-progress agent response + +The `/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/stop-response` API endpoint stops a Spotter agent response that is currently in progress for a given conversation session. + +Use this endpoint when you want to cancel a long-running Spotter response before it completes. The conversation session remains active after you stop a response, so you can send a new query to the same session immediately. + +=== Request parameters + +[width="100%", cols="2,2,4"] +[options='header'] +|===== +|Parameter|Type| Description +|`conversation_identifier`|Path parameter|__String__. Required. The identifier of the active conversation session. Use the value returned by the xref:spotter-agent-conversation-apis.adoc#_create_a_conversation_session_with_spotter_agent[create conversation] API endpoint. +|===== + +This endpoint does not require a request body. + +=== Example request + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/stop-response' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' +---- + +=== Example response + +If the API request is successful, ThoughtSpot stops the in-progress response and returns a 204 response code. + +If the conversation session is not found or has expired, the API returns an error: + +[source,JSON] +---- +{ + "error_code": "CONVERSATION_NOT_FOUND", + "message": "The specified conversation session does not exist or has expired." +} +---- + +== Additional resources + +* See also xref:spotter-agent-apis.adoc[Spotter Agent APIs] +* xref:spotter-agent-streaming-apis.adoc[Spotter agent streaming APIs] +* xref:spotter-agent-process-results-apis.adoc[Process Spotter agent conversation results] +* xref:spotter-agent-data-literacy-apis.adoc[Spotter agent data literacy APIs] +* xref:spotter-agent-sharing-apis.adoc[Spotter agent conversation sharing APIs] +* Visit the +++REST API v2.0 Playground+++ to view the API endpoints and verify the request and response workflows. diff --git a/modules/ROOT/pages/spotter-agent-conversation-mgmt-apis.adoc b/modules/ROOT/pages/spotter-agent-conversation-mgmt-apis.adoc index 371233233..a4bc98671 100644 --- a/modules/ROOT/pages/spotter-agent-conversation-mgmt-apis.adoc +++ b/modules/ROOT/pages/spotter-agent-conversation-mgmt-apis.adoc @@ -42,7 +42,7 @@ __Available on ThoughtSpot Cloud instances from 26.7.0.cl onwards.__ |===== == Saving a conversation -To save a conversation, set the `enable_save_chat` parameter to `true` when sending a xref:spotter-agent-apis.adoc#_create_a_conversation_session_with_spotter_agent[conversation create `POST` request] to the `/api/rest/2.0/ai/agent/conversation/create` API endpoint. +To save a conversation, set the `enable_save_chat` parameter to `true` when sending a xref:spotter-agent-conversation-apis.adoc#_create_a_conversation_session_with_spotter_agent[conversation create `POST` request] to the `/api/rest/2.0/ai/agent/conversation/create` API endpoint. === API request example @@ -96,15 +96,12 @@ curl -X GET \ -H 'Authorization: Bearer {AUTH_TOKEN}' \ ---- -=== Response body +=== API response A successful request returns an HTTP `200` response with top-level fields that include ordered conversation turns (user prompts and agent response items) and sanitized metadata for any files generated by the code-execution tool. When the agent conversation is initiated from a Liveboard, ThoughtSpot automatically seeds the conversation with the existing Liveboard visualization as the first response turn, without any user query. In the API response, this seeded turn appears as the first item in the `messages` array with `user_prompt` set to `null` and `message_id` set to the internal root node identifier of the conversation. All subsequent turns contain a populated `user_prompt`. When rendering conversation history, always check whether `user_prompt` is `null` before attempting to display a user query. -=== API response -A successful request returns an HTTP `200` response with the following top-level fields. The response includes ordered conversation turns (user prompts and agent response items) and sanitized metadata for any files generated by the code-execution tool. - -When the agent conversation is initiated from a Liveboard, ThoughtSpot automatically seeds the conversation with the existing Liveboard visualization as the first response turn, without any user query. In the API response, this seeded turn appears as the first item in the `messages` array with `user_prompt` set to `null` and `message_id` set to the internal root node identifier of the conversation. All subsequent turns contain a populated `user_prompt`. When rendering conversation history, always check whether `user_prompt` is `null` before attempting to display a user query. +=== Response body [width="100%", cols="2,4"] [options="header"] @@ -308,7 +305,7 @@ Each item in `conversations` represents a saved conversation. [options="header"] |===== |Field|Description -|`conversation_identifier`|__String__. Unique identifier of the conversation. Use this value as input in your API requests to the xref:spotter-agent-apis.adoc#_send_queries_to_a_conversation_session[send message], xref:spotter-agent-conversation-mgmt-apis.adoc#update-conversation[update conversation], xref:spotter-agent-conversation-mgmt-apis.adoc#delete-conversation[delete conversation], xref:spotter-agent-apis.adoc#_stop_an_in_progress_agent_response[stop response], and xref:spotter-agent-conversation-mgmt-apis.adoc#load-answer[load answer] endpoints. +|`conversation_identifier`|__String__. Unique identifier of the conversation. Use this value as input in your API requests to the xref:spotter-agent-conversation-apis.adoc#_send_queries_to_a_conversation_session[send message], xref:spotter-agent-conversation-mgmt-apis.adoc#update-conversation[update conversation], xref:spotter-agent-conversation-mgmt-apis.adoc#delete-conversation[delete conversation], xref:spotter-agent-conversation-apis.adoc#_stop_an_in_progress_agent_response[stop response], and xref:spotter-agent-conversation-mgmt-apis.adoc#load-answer[load answer] endpoints. |`conversation_title` a|__String__. Display name of the conversation. |`created_at`|__String__. Timestamp of when the conversation was created. |`updated_at`|__String__. Timestamp of when the conversation was last updated. @@ -473,7 +470,7 @@ curl -X POST \ ---- === API response -A successful request returns the 204 response. The response body contains the updated conversation object reflecting the applied changes. +A successful request returns the 204 response. [#delete-conversation] == Delete a conversation diff --git a/modules/ROOT/pages/spotter-agent-data-literacy-apis.adoc b/modules/ROOT/pages/spotter-agent-data-literacy-apis.adoc new file mode 100644 index 000000000..85ab15a91 --- /dev/null +++ b/modules/ROOT/pages/spotter-agent-data-literacy-apis.adoc @@ -0,0 +1,190 @@ += Spotter agent data literacy APIs +:toc: true +:toclevels: 2 + +:page-title: Spotter agent data literacy APIs +:page-pageid: spotter-agent-data-literacy-apis +:page-description: Use the Spotter data literacy REST APIs to get relevant data source suggestions and decompose a user query into relevant sub-questions. + +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. + +For information about creating a conversation session, see xref:spotter-agent-conversation-apis.adoc[Spotter agent conversation APIs]. + +== Get data source suggestions + +The `POST /api/rest/2.0/ai/data-source-suggestions` API provides relevant data source recommendations for a user-submitted natural language query. To use this API, you must have at least view access to the underlying metadata object referenced in the response. + +=== Request parameters + +[width="100%" cols="2,4"] +[options='header'] +|==== +|Parameter| Description +|`metadata_context` a| Required. Specify one of the following attributes to set the metadata context: + +* `data_source_identifiers` + +__Array of strings__. IDs of the data source object such as Models. +* `answer_identifiers` + +__Array of strings__. GUIDs of the Answer objects that you want to use as metadata. +* `conversation_identifier` + +__String__. ID of the conversation session. +* `liveboard_identifiers` + +__Array of strings__. GUIDs of the Liveboards that you want to use as metadata. + +| `query` |__String__. Required parameter. Specify the query string that needs to be decomposed into smaller, analytical sub-questions. +|`limit_relevant_questions` + +__Optional__ | __Integer__. Sets a limit on the number of sub-questions to return in the response. Default is 5. +|`bypass_cache` + +__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 + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/data-source-suggestions' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "metadata_context": { + "data_source_identifiers": [ + "cd252e5c-b552-49a8-821d-3eadaa049cca" + ] + }, + "query": "Net sales of Jackets in west coast", + "limit_relevant_questions": 3 +}' +---- + +=== API response +If the API request is successful, ThoughtSpot returns a ranked list of data sources, each annotated with relevant reasoning. + +[source,JSON] +---- +{ + "relevant_questions": [ + { + "query": "What is the trend of sales by type over time?", + "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "data_source_name": "(Sample) Retail - Apparel" + }, + { + "query": "Sales by item", + "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "data_source_name": "(Sample) Retail - Apparel" + }, + { + "query": "Sales across regions", + "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "data_source_name": "(Sample) Retail - Apparel" + } + ] +} +---- + +The returned results include metadata such as: + +* `confidence` + +A float indicating the Model's confidence in the relevance of each recommendation. +* `details` + +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. + +During agentic interactions, this API can be used as an integrated tool to decompose user queries and suggest relevant questions for a specific data context. REST clients can also call this API directly to fetch relevant questions via a `POST` request. + +=== Request parameters + +[width="100%" cols="2,4"] +[options='header'] +|===== +|Parameter| Description +|`metadata_context` a| Required. Specify one of the following attributes to set the metadata context: + +* `data_source_identifiers` + +__Array of strings__. IDs of the data source object such as Models. +* `answer_identifiers` + +__Array of strings__. GUIDs of the Answer objects that you want to use as metadata. +* `conversation_identifier` + +__String__. ID of the conversation session. +* `liveboard_identifiers` + +__Array of strings__. GUIDs of the Liveboards that you want to use as metadata. + +| `query` |__String__. Required parameter. Specify the query string that needs to be decomposed into smaller, analytical sub-questions. +|`limit_relevant_questions` + +__Optional__ | __Integer__. Sets a limit on the number of sub-questions to return in the response. Default is 5. +|`bypass_cache` + +__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: + +* `instructions` + +__Array of strings__. Custom user instructions to influence how the AI interprets and processes the query. +* `content` + +__Array of strings__. Additional input such as raw text or CSV-formatted data to enhance context and answer quality. +|===== + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/relevant-questions/' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "metadata_context": { + "data_source_identifiers": [ + "cd252e5c-b552-49a8-821d-3eadaa049cca" + ] + }, + "query": "Net sales of Jackets in west coast", + "limit_relevant_questions": 3 +}' +---- + +=== Example response +If the request is successful, the API returns a set of questions related to the query and metadata context in the `relevant_questions` array. Each object in the `relevant_questions` array contains the following fields: + +* `query` + +A string containing the natural language (NL) sub-question. +* `data_source_identifier` + +GUID of the data source object. +* `data_source_name` + +Name of the associated data source object. + +[source,JSON] +---- +{ + "relevant_questions": [ + { + "query": "What is the trend of sales by type over time?", + "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "data_source_name": "(Sample) Retail - Apparel" + }, + { + "query": "Sales by item", + "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "data_source_name": "(Sample) Retail - Apparel" + }, + { + "query": "Sales across regions", + "data_source_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "data_source_name": "(Sample) Retail - Apparel" + } + ] +} +---- + +== Additional resources + +* See also xref:spotter-agent-apis.adoc[Spotter Agent APIs] +* xref:spotter-agent-conversation-apis.adoc[Spotter agent conversation APIs] +* xref:spotter-agent-process-results-apis.adoc[Process Spotter agent conversation results] diff --git a/modules/ROOT/pages/spotter-agent-instructions.adoc b/modules/ROOT/pages/spotter-agent-instructions.adoc index 530177958..6da45c29a 100644 --- a/modules/ROOT/pages/spotter-agent-instructions.adoc +++ b/modules/ROOT/pages/spotter-agent-instructions.adoc @@ -63,9 +63,7 @@ curl -X PUT \ === Example response -If the API request is successful, ThoughtSpot returns an HTTP `200` response with the following agent instruction properties: - -If the request is successful, the response includes the saved AgentInstructions record: +If the API request is successful, ThoughtSpot returns an HTTP `200` response with the saved AgentInstructions record, which includes the following properties: * `id`: unique identifier of the record * `instructions`: the saved instructions text diff --git a/modules/ROOT/pages/spotter-agent-process-results-apis.adoc b/modules/ROOT/pages/spotter-agent-process-results-apis.adoc new file mode 100644 index 000000000..624011214 --- /dev/null +++ b/modules/ROOT/pages/spotter-agent-process-results-apis.adoc @@ -0,0 +1,46 @@ += Export answers generated from a Spotter conversation +:toc: true +:toclevels: 2 + +:page-title: Export answers generated from a Spotter conversation +:page-pageid: process-conversation-output +:page-description: Export or download the Answer data generated by a Spotter agent conversation session using the Answer report API. + +When the Spotter AI agent generates an Answer in a conversation session, you can use the Answer report API to export or download that Answer. + +For information about sending queries to a conversation session, see xref:spotter-agent-conversation-apis.adoc[Spotter agent conversation APIs]. For information about the streaming response format, see xref:spotter-agent-streaming-apis.adoc[Spotter agent streaming APIs]. + +[#process_results] +== Process results generated from a conversation session +To export or download the Answer data generated by the Spotter APIs, use the xref:report-apis-v2.adoc#exportSpotterData[Answer report] API. + +The `session_id` and `gen_no` values of the `answer` event metadata generated from the Spotter conversation API response are required to identify the answer to export. + +NOTE: Requires at least view access to the Answer. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/answer' \ + -H 'Authorization: Bearer {Bearer_token}' \ + -H 'Accept: application/octet-stream' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "session_identifier": "sess-abc-123", + "generation_number": 1, + "file_format": "CSV" +}' +---- +The `file_format` parameter accepts `PDF`, `PNG`, `CSV`, or `XLSX`. + +[NOTE] +==== +Using tokens generated by the Spotter API in a xref:data-apis-v2.adoc#_search_data_api[Search Data API] request can return invalid column errors, because these tokens may reference formulas or columns not present in the data model. Instead, use the xref:report-apis-v2.adoc#exportSpotterData[Answer report] API and include the session ID and generation number obtained from the Spotter API in your API request to retrieve the data. +==== + +== Additional resources + +* See also xref:spotter-agent-apis.adoc[Spotter Agent APIs] +* xref:spotter-agent-conversation-apis.adoc[Spotter agent conversation APIs] +* xref:spotter-agent-streaming-apis.adoc[Spotter agent streaming APIs] +* xref:spotter-agent-data-literacy-apis.adoc[Spotter agent data literacy APIs] diff --git a/modules/ROOT/pages/spotter-agent-sharing-apis.adoc b/modules/ROOT/pages/spotter-agent-sharing-apis.adoc new file mode 100644 index 000000000..961315f26 --- /dev/null +++ b/modules/ROOT/pages/spotter-agent-sharing-apis.adoc @@ -0,0 +1,365 @@ += Spotter agent conversation sharing APIs +:toc: true +:toclevels: 2 + +:page-title: Spotter agent conversation sharing APIs +:page-pageid: spotter-agent-sharing-apis +:page-description: Use the Spotter agent conversation sharing REST API v2.0 endpoints to share saved Spotter agent conversations with other users or groups. + +You can share a Spotter conversation with other users and groups and manage shared content programmatically using REST API endpoints. + +== Supported endpoints + +[width="100%" cols="1"] +|===== +a| `POST /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/share` + +xref:spotter-agent-sharing-apis.adoc#_share_a_conversation[Shares a saved Spotter conversation, grants or revokes access to a shared conversation] for one or more principals. + +__Available on ThoughtSpot Cloud instances from 26.9.0.cl onwards.__ + +a| `GET /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/get-shared-content` + +xref:spotter-agent-sharing-apis.adoc#_get_shared_content[Returns the read-only view of the shared conversation], including messages and associated answers. + +__Available on ThoughtSpot Cloud instances from 26.9.0.cl onwards.__ + +a| `GET /api/rest/2.0/ai/agent/conversations/{conversation_identifier}/get-share-info` + +xref:spotter-agent-sharing-apis.adoc#_get_share_information[Returns sharing state and metadata], and the list of principals that can access the shared content. + +__Available on ThoughtSpot Cloud instances from 26.9.0.cl onwards.__ +|===== + +For information about creating, saving, and managing saved conversation, see xref:spotter-agent-conversation-apis.adoc[Spotter agent conversation APIs] and xref:spotter-agent-conversation-mgmt-apis.adoc[APIs for managing saved conversations]. + +== Required privileges + +* To use these APIs, you need the `CAN_USE_SPOTTER` (*Can use Spotter*) privilege. +* To share a conversation or view the sharing status, you must be the owner of the conversation. Only the user who created the conversation can manage its share access. +* To retrieve shared content, you must be the conversation owner or a principal (user or group) that has been granted access. + +[NOTE] +==== +The shared view is a read-only snapshot of the conversation at the time of sharing. Recipients cannot send messages or modify the conversation. +==== + +[#_share_a_conversation] +== Share a conversation +To share a conversation with other ThoughtSpot users and groups, refresh shared content, or revoke access, send a `POST` request to the `/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/share` endpoint. When principals are added, ThoughtSpot creates a read-only shared view of the conversation from its current state. + +The conversation to share is identified by the `conversation_identifier` URL path parameter. In your API request, you must include the GUID of the saved Spotter conversation as a path parameter and add the attributes to grant or revoke access in the request body. + +[NOTE] +==== +Do not include the same principal identifiers in both `grant` and `revoke` arrays in the same request. +==== + +=== Request parameters + +[width="100%" cols="2,4"] +[options="header"] +|===== +| Parameter | Description +| `grant` |__Array of strings__. Array of principals to grant access to the conversation specified in the request. Specify `principal_identifier` and `principal_type`. Specify the principal type, name or GUID of the intended recipients. All recipients are granted a `READ_ONLY` access. +| `revoke` |__Array of strings__. Principals to revoke access from. Specify `principal_identifier` and `principal_type`. Specify the principal type, name or GUID of the recipients to revoke access from. +| `refresh_shared_content` |__Boolean__. When set to `true`, ThoughtSpot regenerates the shared view from the latest conversation state, even if a shared view already exists. When `false`, reuses the existing shared view. Default is `false`. +//| `notify_on_share` |__Boolean__. When set to `true`, ThoughtSpot sends an in-app notification to the recipients of the shared content. Default is `true`. Available from 26.10.0.cl. +|===== + +=== Request examples + +Grant access to a conversation:: + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/share' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "refresh_shared_content": false, + "grant": [ + { "principal_identifier": "user-001", "principal_type": "USER" }, + { "principal_identifier": "group-001", "principal_type": "USER_GROUP" } + ], + "revoke": [] +}' +---- + +Revoke access granted to a shared conversation:: + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/share' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "refresh_shared_content": false, + "grant": [], + "revoke": [ + { "principal_identifier": "user-001", "principal_type": "USER" }, + { "principal_identifier": "group-001", "principal_type": "USER_GROUP" } + ] +}' +---- + +Refresh shared content:: +To regenerate the shared snapshot for existing recipients without changing access, set `refresh_shared_content` to `true` with empty `grant` and `revoke` arrays. ++ +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/share' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "refresh_shared_content": true, + "grant": [], + "revoke": [] +}' +---- + +Refresh shared content and update access details:: +To update access and refresh the snapshot in a single call, combine `refresh_shared_content: true` with the recipient details in the `grant` or `revoke` array. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/share' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "refresh_shared_content": true, + "grant": [ + { "principal_identifier": "user-002", "principal_type": "USER" }, + { "principal_identifier": "group-002", "principal_type": "USER_GROUP" } + ] +}' +---- + +=== API response +If the request is successful, ThoughtSpot returns a 204 response code. + +[#_get_shared_content] +== Get shared conversation content +To retrieve the full read-only view of a shared conversation, including ordered messages and data source metadata, send a `GET` request to the `/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/get-shared-content` endpoint. This endpoint is accessible to the conversation owner and any principal that has been granted access. + +Use this endpoint to render a shared conversation in a UI or to retrieve its content for post-processing. + +=== Request parameters + +[width="100%"] +[options='header'] +|===== +|Parameter|Type|Description +|`conversation_identifier`|String|The unique ID of the source conversation. +|===== + +=== Example request + +[source,cURL] +---- +curl -X GET \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/get-shared-content' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' +---- + +=== API response +If the request is successful, the API returns the shared conversation content with the following fields: + +[source,JSON] +---- +{ + "conversation_id": "conv-abc-123", + "shared_conversation_id": "snap-xyz-456", + "conversation_title": "Sales by Region Q1", + "creator_user_id": "5d3e6cc7-2f4a-4b0e-9a1c-8f2b6d4e7a10", + "data_sources": [{ "id": "ds-001", "name": "Retail Sales" }], + "analyst_ids": ["spot-7f2a"], + "messages": [ + { + "message_id": "node-u-01", + "timestamp_in_millis": 1744000000000, + "user_prompt": { + "message": { + "message_id": "msg-u-01", + "content": "Show me revenue by region." + }, + "attachments": [] + }, + "response_items": [ + { + "type": "tool_call", + "tool_call_id": "toolu-01", + "tool_name": "search_datasets", + "step_title": "Searching datasets", + "arguments": { "query": "revenue by region" }, + "timestamp_in_millis": 1744000001000, + "is_thinking": false + }, + { + "type": "answer", + "answer_id": "ans-01", + "tool_call_id": "toolu-02", + "tool_name": "fetch_and_visualize", + "step_title": "Visualizing", + "timestamp_in_millis": 1744000004000, + "is_thinking": false + }, + { + "type": "text", + "content": "Revenue is highest in APAC.", + "content_type": "TEXT_MARKDOWN", + "timestamp_in_millis": 1744000005000, + "is_thinking": false, + "step_title": null, + "file_reference": null + } + ] + } + ], + "code_execution_files": [ + { + "file_id": "revenue_by_region.csv", + "display_name": "revenue_by_region.csv", + "file_type": "csv", + "created_time_in_millis": 1744027200000, + "expired": false + } + ] +} +---- + +==== Response fields + +[width="100%"] +[options='header'] +|===== +|Field|Description +|`conversation_id`|__String__. Conversation ID sent in the request parameter. +|`shared_conversation_id`|__String__. Id of the shared snapshot. This is not the same as `conversation_id`. Pass this value as the `conversation_identifier` parameter in `loadAnswer` calls. This value changes each time the snapshot is refreshed via the share endpoint with `refresh_shared_content: true`. +|`conversation_title`|__String__. Display title of the conversation. `null` if no title was set. +|`creator_user_id`|__String__. Id of the user who created and shared the conversation. This is the original creator, not the caller retrieving the shared content. +|`data_sources`|__Array of strings__. Array of data sources used by the conversation. Each entry includes the `id` and display `name` of the data source. +|`analyst_ids`|__Array of strings__. Array of the identifiers of the AI analysts the conversation ran against. An analyst is a purpose-built agent configured over a set of data sources, with its own instructions and access rules. An empty array is returned if the conversation is not associated with any analyst. +|`messages`|__Array of conversation messages__. Ordered conversation messages, from oldest to newest. The structure is the same as returned by the get conversation endpoint. An empty array is returned when the conversation has no messages. +a|`code_execution_files`|__Array of code execution files__. Sanitized metadata for files generated by the code execution tool. Each entry in the `code_execution_files` array contains the following attributes: + +* `file_id`. __String__. Unique identifier of the file. +* `display_name`. __String__. Name of the file. +* `file_type`. __String__. File type, such as `csv`, `pdf`, or `png`. +* `created_time_in_millis`. __Long__. Milliseconds since Unix epoch when the file was created. +* `expired`.__Boolean__. When `true`, the underlying file is no longer retrievable from code execution storage. Disable download and preview options in your UI for expired files. + +If there are no code execution steps, an empty array is returned. +|===== + +=== Load answer payloads from a shared view +The full answer payload is not embedded in messages. Each `answer` response item in `messages[].response_items` contains an `answer_id` field. To retrieve the full answer payload, call `loadAnswer` with: + +* `conversation_identifier`: the `shared_conversation_id` value from this response. +* `answer_id`: the `answer_id` from the `answer` response item. + +[IMPORTANT] +==== +`shared_conversation_id` is not the same as `conversation_id`. It identifies the shared snapshot, which is a separate internal object from the source conversation. Always use the `shared_conversation_id` value as the `conversation_identifier` parameter when calling `loadAnswer` to hydrate answers from a shared view. Because this value changes each time the snapshot is refreshed, re-fetch the shared content to get the current value before calling `loadAnswer`. +==== + + +[#_get_share_information] +== Get share information +To view the current share state of a conversation you own, send a `GET` request to the `/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/get-share-info` endpoint. The response shows whether the shared view reflects the latest conversation content and lists the principals that currently have access. + +Use this endpoint to render a share management UI, audit who has access to a conversation, or determine whether the shared view needs to be refreshed before sending a link. + +=== Request parameters + +[width="100%"] +[options='header'] +|===== +|Parameter|Description +|`conversation_identifier`|__String__. The unique ID of the conversation, as returned when creating a conversation or listing conversations. +|===== + +=== Example request + +[source,cURL] +---- +curl -X GET \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversations/{conversation_identifier}/get-share-info' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' +---- + +=== API response + +The following example shows the response for a conversation that is shared and current: + +[source,JSON] +---- +{ + "conversation_id": "conv-abc-123", + "is_shared_content_outdated": false, + "principals": [ + { + "id": "user-001", + "type": "USER", + "display_name": "Alice Example", + "name": "alice.example", + "permission": "READ_ONLY" + }, + { + "id": "group-001", + "type": "USER_GROUP", + "display_name": "Sales Team", + "name": "sales-team", + "permission": "READ_ONLY" + } + ] +} +---- + +The following example shows the response for a conversation that has never been shared: + +[source,JSON] +---- +{ + "conversation_id": "conv-abc-123", + "is_shared_content_outdated": null, + "principals": [] +} +---- + +When `is_shared_content_outdated` is `true`, call the share endpoint with `refresh_shared_content: true` to update the shared view with the latest conversation content. + + +==== Response fields + +[width="100%"] +[options='header'] +|===== +|Field|Description +|`conversation_id`|__String__. Echoes the request parameter. +|`is_shared_content_outdated` a|__Boolean__. + +* `true`, if the shared view was generated before the last edit to the conversation and does not reflect the latest content +* `false` when the shared view is current. +* `null` when the conversation has never been shared. +|`principals`|__Array of strings__. List of principals with access. Empty when no access has been granted. The conversation owner is never included. Each entry in the `principals` array contains the following attributes: + +* `id`. __String__. Unique identifier of the user or group. +* `type`. __String__. `USER` for individual users, `USER_GROUP` for groups. +* `display_name`. __String__. Display name as shown in the ThoughtSpot UI. +* `name`. __String__. Internal name of the user or group. +* `permission`. __String__. Access level. Always `READ_ONLY` for shared conversations. + +|===== + +== Additional resources + +* xref:spotter-agent-apis.adoc[Spotter Agent APIs] +* xref:spotter-agent-conversation-apis.adoc[Spotter agent conversation APIs] +* xref:spotter-agent-conversation-mgmt-apis.adoc[APIs for managing saved conversations] +* xref:customize-spotter-sharing.adoc#_spotter_conversation_sharing[Spotter conversation sharing in embedded views] + diff --git a/modules/ROOT/pages/spotter-agent-streaming-apis.adoc b/modules/ROOT/pages/spotter-agent-streaming-apis.adoc new file mode 100644 index 000000000..3094ce90a --- /dev/null +++ b/modules/ROOT/pages/spotter-agent-streaming-apis.adoc @@ -0,0 +1,662 @@ += Spotter agent streaming APIs +:toc: true +:toclevels: 3 + +:page-title: Spotter agent streaming APIs +:page-pageid: spotter-agent-streaming-apis +:page-description: Use the Spotter agent streaming REST API to receive real-time Server-Sent Events (SSE) responses for conversational queries sent to the Spotter agent. + +ThoughtSpot's Spotter agent streaming API lets you send natural language queries to an existing conversation session and receive the response as a real-time Server-Sent Events (SSE) stream, instead of waiting for the complete response. + +For information about creating a conversation session and sending queries to it, see xref:spotter-agent-conversation-apis.adoc[Spotter agent conversation APIs]. + +== Send a query to agent and get streaming responses + +To send queries to an ongoing conversation session with Spotter agent and receive streaming responses, use the `/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send/stream` API endpoint. This API endpoint uses the SSE protocol to deliver data incrementally in real time, rather than waiting for the entire response to be generated before sending it to the client. + +The `/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send/stream` API can be used as an integrated tool for real-time streaming of conversational interactions between agents and the ThoughtSpot backend. + +=== Request parameters + +[width="100%" cols="2,4"] +[options='header'] +|===== +|Parameter| Description +|`conversation_identifier` |__String__. Specify the conversation ID received from the xref:spotter-agent-conversation-apis.adoc#_create_a_conversation_session_with_spotter_agent[POST /api/rest/2.0/ai/agent/conversation/create] API call. +|`messages`|_Array of strings_. Include at least one natural language query. For example, `Sales data for Jackets`, `Top performing products in the west coast`. +|===== + +=== Example request + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/agent/conversation/{conversation_identifier}/send/stream' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "conversation_identifier": "h2I_pTGaRQof", + "messages": [ + "Net sales of Jackets" + ] +}' +---- + +=== API response + +If the API request is successful, the response includes a stream of events, each containing a partial or complete message from the AI agent, rather than a single JSON object. + +Each event is a simple text-based message in a specific format, `data: \n\n`; `\n\n` means that each message sent from the server to the client is prefixed with the `data:` keyword, followed by the actual payload (``), and ends with two newline characters (`\n\n`). + +The API uses this format so that the clients can reconstruct the AI-generated response as it streams in, chunk by chunk, and show the responses in real-time. In agentic workflows, the receiving client or agent listens to the SSE stream, parses each event, and assembles the full response for its users. + +==== Example response +If the request is valid, the API returns SSE streams. Each line has the form `data: [{"type": "...", ...}]`, a JSON array of event objects. + +[source,JSON] +---- +data: [{"type":"ack","node_id":"aGxzcFVrtom8"}] + +data: [{"type":"conv_title","title":"Sales 2025 vs 2024","conv_id":"-XIi04l5rrof"}] + +data: [{"type":"notification","group_id":"cDEsAQbSnd3J","metadata":{"type":"thinking","tool_title":"Analyzing Sales Performance: 2025 vs 2024"},"code":"TOOL_CALL_NOTIFICATION"}] + +data: [{"id":"mNAdvy-NK2l6","type":"text-chunk","group_id":"cDEsAQbSnd3J","metadata":{"format":"markdown","type":"thinking"},"content":"\n\nI need to compare sales performance between 2025 and 2024."}] + +data: [{"type":"notification","group_id":"m1MTvttEUa7o","code":"nls_start"}] + +data: [{"id":"hxWMDP-pgR3B","type":"answer","group_id":"m1MTvttEUa7o","metadata":{"sage_query":"[sales] [date] = '2025' vs [date] = '2024'","session_id":"431adcf9-1328-4d8c-81a1-0faa7fa37ba6","title":"Compare sales for 2025 vs 2024"},"title":"Compare sales for 2025 vs 2024"}] + +data: [{"type":"notification","code":"FINAL_RESPONSE_NOTIFICATION"}] +---- +For the complete response in one payload, use the xref:spotter-agent-conversation-apis.adoc#_send_queries_to_a_conversation_session[`/send` endpoint] instead. + +//// +[source,] +---- +data: [{"type": "ack", "node_id": "BRxCtJ-aGt8l"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": "I"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " understand"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " you're"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " interested"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " in"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " the"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " net"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " sales"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " of"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " Jackets"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": "."}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " I'll"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " retrieve"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " the"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " relevant"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " data"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " for"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": " you"}] + +data: [{"id": "OJ0zMh4PVa-y", "type": "text-chunk", "group_id": "czoDDhNwwU7z", "metadata": {"format": "markdown"}, "content": "."}] + +data: [{"type": "notification", "group_id": "o8dQ9SAWdtrL", "metadata": {"title": "Net sales of Jackets"}, "code": "nls_start"}] + +data: [{"type": "notification", "group_id": "o8dQ9SAWdtrL", "code": "QH", "message": "Fetching Worksheet Data"}] + +data: [{"type": "notification", "group_id": "o8dQ9SAWdtrL", "code": "TML_GEN", "message": "Translating your query with the Reasoning Engine"}] + +data: [{"type": "notification", "group_id": "o8dQ9SAWdtrL", "code": "ANSWER_GEN", "message": "Verifying results with the Trust Layer"}] + +data: [{"id": "r24X7D99SROD", "type": "answer", "group_id": "o8dQ9SAWdtrL", "metadata": {"sage_query": "[sales] [item type] = [item type].'jackets'", "session_id": "b321b404-cbf1-4905-9b0c-b93ad4eedf89", "gen_no": 1, "transaction_id": "6874259d-13b1-478c-83cb-b3ed52628850", "generation_number": 1, "warning_details": null, "ambiguous_phrases": null, "query_intent": null, "assumptions": "You want to see the total sales amount for jackets item type.", "tml_phrases": ["[sales]", "[item type] = [item type].'jackets'"], "cached": false, "sub_queries": null, "title": "Net sales of Jackets", "worksheet_id": "cd252e5c-b552-49a8-821d-3eadaa049cca"}, "title": "Net sales of Jackets"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "The"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " net"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " sales"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " for"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " Jackets"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " have"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " been"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " visual"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "ized"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " for"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " you"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "."}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " This"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " analysis"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " specifically"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " filtered"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " for"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " the"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " item"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " type"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "jackets"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "\""}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " and"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " calculated"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " the"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " total"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " sales"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " amount"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " associated"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " with"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " those"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " products"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ".\n\n"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "**"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "Summary"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " &"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " Insights"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ":"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "**\n"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "-"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " The"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " visualization"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " shows"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " the"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " total"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " net"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " sales"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " for"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " all"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " jacket"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " transactions"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " in"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " your"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " apparel"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " dataset"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ".\n"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "-"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " The"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " calculation"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " uses"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " only"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " sales"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " amounts"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " where"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " the"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " item"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " type"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " is"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " \""}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "J"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "ackets"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ".\"\n"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "-"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " This"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " information"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " is"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " useful"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " for"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " understanding"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " the"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " revenue"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " contribution"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " of"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " jackets"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " within"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " your"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " product"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " mix"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ".\n\n"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "If"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " you'd"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " like"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " to"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " see"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " a"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " breakdown"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " by"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " region"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ","}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " state"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ","}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " time"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " period"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ","}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " or"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " compare"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " jacket"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " sales"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " to"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " other"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " product"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " types"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": ","}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " please"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " let"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " me"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": " know"}] + +data: [{"id": "BgY16KR8nVL1", "type": "text-chunk", "group_id": "_ARJXDKbFhHF", "metadata": {"format": "markdown"}, "content": "!"}] +---- +//// + +==== SSE event types +The SSE event types streamed in the API response include: + +* `ack` + +Confirms receipt of the request. For example, the type in the first message `data: [{"type": "ack", "node_id": "BRxCtJ-aGt8l"}]`, which indicates that the server has received the client's request and is acknowledging it. +* `conv_title` + +A conversation title (`title`, `conv_id`). +* `notification` + +Progress or status update (`group_id`, `metadata`, `code`). For example, `TOOL_CALL_NOTIFICATION`, `nls_start`, `FINAL_RESPONSE_NOTIFICATION`. +* `type` + +Type can be `thinking`, `text`. +* `text` + +Complete text block in markdown format. +* `text-chunk` + +Text fragments in incremental streaming, often in markdown (`id`, `group_id`, `metadata` with `format`) +* `content` + +The actual text content sent incrementally. For example, `"I"`, `"understand"`, `"you're"`, `"interested"`, `"in"`, `"the"`, `"net"`, `"sales"`, and so on. +* `answer` + +Structured answer with metadata (`id`, `group_id`, `metadata` with `sage_query`, `session_id`, `title` and more) +* `error` + +In case of failures. +* `*-interrupt` + +If the generation was stopped mid-stream. +* `group_id` + +Groups related chunks together. + +For more information and examples, see xref:spotter-agent-streaming-apis.adoc#_sse_event_payload_reference[SSE event payload reference]. + +=== Thinking versus output events +Spotter responses have two phases: + +* A *thinking phase*, where the AI reasons through the query and calls internal tools, followed by an *output phase* containing the final response delivered to the user. + + +Events in the thinking phase carry `"metadata": { "type": "thinking" }`. All other events are final output. + +Every event includes a `group_id`. Events sharing the same `group_id` belong together. During the thinking phase, each tool call gets its own `group_id`. A `FINAL_RESPONSE_NOTIFICATION` notification marks the boundary between the thinking and output phases. + +[listing] +---- +THINKING PHASE +─────────────────────────────────────────────────────────── +ack + +┌─ group_id: g1 ── Tool Call 1 ("Searching data") ─────────┐ +│ notification (thinking, TOOL_CALL_NOTIFICATION) │ +│ text-chunk (thinking) │ +│ answer (thinking) │ +└──────────────────────────────────────────────────────────┘ + +┌─ group_id: g2 ── Tool Call 2 ("Running code") ───────────┐ +│ notification (thinking, TOOL_CALL_NOTIFICATION) │ +│ text-chunk (thinking) │ +│ text-chunk (thinking) │ +└──────────────────────────────────────────────────────────┘ + +notification (FINAL_RESPONSE_NOTIFICATION) ←── boundary +──────────────────────────────────────────────────────────── + +OUTPUT PHASE +──────────────────────────────────────────────────────────── +┌─ group_id: g3 ────────────────────────────────────────────┐ +│ text "Here are the results:" │ +│ answer (final visualization) │ +└───────────────────────────────────────────────────────────┘ +[stream closes] +---- + +==== Notification codes reference + +[width="100%" cols="2,4"] +[options='header'] +|===== +|Code| When it appears +|`QH`|Query handling started +|`TML_GEN` / `TML_GEN_RETRY`|Generating or retrying TML +|`ANSWER_GEN`|Generating an answer +|`IDENTIFYING_ATTRIBUTES`|Identifying data attributes +|`PERFORMING_CHANGE_ANALYSIS`|Running change analysis +|`PERFORMING_FORECASTING_ANALYSIS`|Running forecasting +|`SUMMARIZING_RESULTS`|Summarizing results +|`TOOL_CALL_NOTIFICATION`|Tool invocation (during thinking phase) +|`FINAL_RESPONSE_NOTIFICATION`|Marks the transition from thinking to output +|`search_datasets_start` / `search_datasets_end`|Data source discovery in progress or complete +|`approval_required`|An external tool requires user permission before proceeding +|===== + +=== SSE event payload reference + +==== ack + +[source,JSON] +---- +data: { + "type": "ack", + "group_id": "a1b2c3", + "id": "evt-001", + "node_id": "resp-node-abc" +} +---- + +==== notification (thinking — tool call) + +[source,JSON] +---- +data: { + "type": "notification", + "group_id": "g1", + "id": "evt-002", + "code": "TOOL_CALL_NOTIFICATION", + "message": "Searching for relevant data", + "metadata": { + "type": "thinking", + "tool_title": "Searching sales data", + "tool_code": "RUNNING_CODE_EXECUTION", + "tool_name": "code_interpreter" + } +} +---- + +==== notification (thinking - external tool with MCP integration) + +[source,JSON] +---- +data: { + "type": "notification", + "group_id": "g2", + "id": "evt-003", + "code": "TOOL_CALL_NOTIFICATION", + "message": "Querying Salesforce", + "metadata": { + "type": "thinking", + "tool_title": "Salesforce: Get Opportunities", + "tool_name": "get_opportunities", + "integration_id": "int-sf-123", + "integration_name": "Salesforce" + } +} +---- + +==== notification (approval required) +Sent when an external MCP tool requires explicit user permission before proceeding. Your application should prompt the user to approve or deny the action before continuing. + +[source,JSON] +---- +data: { + "type": "notification", + "group_id": "g2", + "id": "evt-005", + "code": "approval_required", + "metadata": { + "request_id": "perm-req-789", + "integration_id": "int-sf-123", + "integration_name": "Salesforce", + "tool_name": "get_opportunities", + "annotated_title": "Access Salesforce Opportunities" + } +} +---- + +==== notification (FINAL_RESPONSE_NOTIFICATION) + +[source,JSON] +---- +data: { + "type": "notification", + "group_id": "g1", + "id": "evt-004", + "code": "FINAL_RESPONSE_NOTIFICATION", + "message": "" +} +---- + +==== text + +[source,JSON] +---- +data: { + "type": "text", + "group_id": "g3", + "id": "evt-007", + "content": "Here is the total revenue breakdown by region for Q4 2025:\n\n- **North America:** $4.2M\n- **EMEA:** $2.8M\n- **APAC:** $1.5M" +} +---- + +==== text-chunk +Multiple chunks sharing the same `id` should be appended together to reconstruct the full text item. + +[source,JSON] +---- +data: { "type": "text-chunk", "group_id": "g3", "id": "evt-009", "content": "Based on the analysis, " } +data: { "type": "text-chunk", "group_id": "g3", "id": "evt-009", "content": "revenue grew 12% quarter-over-quarter." } +---- + +==== answer +When an `answer` event is received, the `session_id` and `gen_no` fields are returned. You can export the visualization data using the Export Answer Report API to process the results. This allows users to download the answer as a PDF, PNG, CSV, or XLSX file. + +[source,JSON] +---- +data: { + "type": "answer", + "group_id": "g3", + "id": "evt-010", + "title": "Revenue by Region Q4 2025", + "metadata": { + "session_id": "sess-abc-123", + "gen_no": 1, + "transaction_id": "txn-456", + "worksheet_id": "ws-def-789", + "cached": false, + "is_hidden": false + } +} +---- + +==== search_datasets +Emitted as a start/end pair during Auto mode data source discovery. + + +[source,JSON] +---- +data: { "type": "search_datasets", "group_id": "g0", "id": "evt-012", "code": "search_datasets_start", "metadata": {} } + +data: { + "type": "search_datasets", + "group_id": "g0", + "id": "evt-013", + "code": "search_datasets_end", + "metadata": { + "data_sources": [ + { "worksheet_id": "ws-1", "worksheet_name": "Sales Data", "confidence": "high", "reasoning": "Contains revenue columns" }, + { "worksheet_id": "ws-2", "worksheet_name": "Marketing Data", "confidence": "low", "reasoning": "No revenue columns" } + ], + "auto_selected": { "worksheet_id": "ws-1", "worksheet_name": "Sales Data", "confidence": "high", "reasoning": "Best match" } + } +} +---- +==== file + +[source,JSON] +---- +data: { + "type": "file", + "group_id": "g3", + "id": "evt-014", + "files": [ + { "ts_file_id": "file-abc-001", "display_name": "quarterly_report.csv", "file_type": "csv", "created_at": "2025-11-15T10:30:00Z" }, + { "ts_file_id": "file-abc-002", "display_name": "chart.png", "file_type": "png", "created_at": "2025-11-15T10:30:01Z" } + ], + "metadata": { "conv_id": "conv-123" } +} +---- +==== conv_title + +[source,JSON] +---- +data: { + "type": "conv_title", + "group_id": "g0", + "id": "evt-015", + "title": "Revenue Analysis Q4 2025", + "conv_id": "conv-123" +} +---- + +==== error + +[source,JSON] +---- +data: { + "type": "error", + "group_id": "g3", + "id": "evt-016", + "code": "RATE_LIMIT_EXCEEDED", + "message": "Too many requests", + "display_message": "You've exceeded the rate limit. Please try again in a few minutes." +} +---- +==== agent-interrupt +Sent when generation is stopped mid-stream. + +[source,JSON] +---- +data: { + "type": "notification", + "group_id": "g3", + "id": "evt-017", + "code": "agent-interrupt", + "message": "Generation stopped" +} +---- + +== Additional resources + +* See also xref:spotter-agent-apis.adoc[Spotter Agent APIs] +* xref:spotter-agent-conversation-apis.adoc[Spotter agent conversation APIs] +* xref:spotter-agent-process-results-apis.adoc[Process Spotter agent conversation results] +* xref:spotter-agent-sharing-apis.adoc[Spotter agent conversation sharing APIs] diff --git a/modules/ROOT/pages/spotter-ai-memory-api.adoc b/modules/ROOT/pages/spotter-ai-memory-api.adoc index 0c87f4f04..044fb58ea 100644 --- a/modules/ROOT/pages/spotter-ai-memory-api.adoc +++ b/modules/ROOT/pages/spotter-ai-memory-api.adoc @@ -405,7 +405,7 @@ The import operation deletes and replaces the existing global memories on the re [source,cURL] ---- curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/memory/export' \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/ai/memory/import' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {AUTH_TOKEN}' \ diff --git a/modules/ROOT/pages/spotter-apis.adoc b/modules/ROOT/pages/spotter-apis.adoc index a5759e1b9..a9e29c858 100644 --- a/modules/ROOT/pages/spotter-apis.adoc +++ b/modules/ROOT/pages/spotter-apis.adoc @@ -25,6 +25,11 @@ For information about supported API operations, see the following pages: * xref:spotter-classic-apis.adoc[APIs for Spotter classic workflow] * xref:spotter-agent-apis.adoc[APIs for Spotter agent workflows] +* xref:spotter-agent-conversation-apis.adoc[APIs for Spotter agent conversations] +* xref:spotter-agent-streaming-apis.adoc[APIs for Spotter agent streaming responses] +* xref:spotter-agent-process-results-apis.adoc[APIs for processing Spotter agent conversation results] +* xref:spotter-agent-data-literacy-apis.adoc[APIs for Spotter agent data literacy] +* xref:spotter-agent-sharing-apis.adoc[APIs for sharing Spotter conversations] * xref:spotter-agent-conversation-mgmt-apis.adoc[APIs for Spotter conversation management] * xref:spotter-nl-instructions.adoc[APIs for Spotter coaching and data model instructions] * xref:spotter-agent-instructions.adoc[APIs for Spotter agent instructions] @@ -33,7 +38,7 @@ For information about supported API operations, see the following pages: When using the xref:spotter-classic-apis.adoc#_generate_a_single_answer[Single Answer] and xref:spotter-classic-apis.adoc#_send_a_query_to_a_conversation_session[Send message] APIs, the locale used for API requests depends on your application's locale settings: -* If your application is set to "Use browser language", the API will use this locale to generate responses. To override this setting, you must explicitly include the desired locale code in the `Accept-Language` header of your API request. To ensure consistent localization, set the `Accept-Language` header in your API requests when relying on browser language detection, or configure the locale explicitly in the user profile settings in ThoughtSpot. +* If your application is set to "Use browser language," the API will not apply the default locale. In this case, you must explicitly include the desired locale code in the `Accept-Language` header of your API request. If you do not specify the locale, the API may not return responses in the expected language or regional format. * If you have set a specific locale in your ThoughtSpot instance or user profile, the API uses this locale to generate responses, overriding the browser or OS locale. == Per-user API rate limits diff --git a/modules/ROOT/pages/spotter-classic-apis.adoc b/modules/ROOT/pages/spotter-classic-apis.adoc index 2d8bb534a..bd0d088c1 100644 --- a/modules/ROOT/pages/spotter-classic-apis.adoc +++ b/modules/ROOT/pages/spotter-classic-apis.adoc @@ -57,7 +57,7 @@ Include the following parameters in the request body: [options='header'] |===== |Form parameter|Description -|`metadata_identifier`|_String_. Required. Specify the GUID of the data source objects such as ThoughtSpot Models. The metadata object specified in the API request will be used as a data source for the conversation. +|`metadata_identifier`|_String_. Required. Specify the GUID of the data source object or model. The metadata object specified in the API request will be used as a data source for the conversation. |`tokens` + __Optional__ a|_String_. To set the context for the conversation, you can specify a set of keywords as token string. For example, `[sales],[item type],[state]`. |===== diff --git a/modules/ROOT/pages/spotter-nl-instructions.adoc b/modules/ROOT/pages/spotter-nl-instructions.adoc index 39337d54f..205da6218 100644 --- a/modules/ROOT/pages/spotter-nl-instructions.adoc +++ b/modules/ROOT/pages/spotter-nl-instructions.adoc @@ -49,7 +49,7 @@ curl -X POST \ "nl_instructions_info": [ { "instructions": [ - "When I ask for last month, use 'last 30 days' as a filter.", + "When I ask for last month, use '\''last 30 days'\'' as a filter.", "Exclude orders where order_status = '\''CANCELLED-USER'\'' when calculating total revenue" ], "scope": "GLOBAL" diff --git a/modules/ROOT/pages/timezone.adoc b/modules/ROOT/pages/timezone.adoc index 839794371..8b34b2cd9 100644 --- a/modules/ROOT/pages/timezone.adoc +++ b/modules/ROOT/pages/timezone.adoc @@ -298,6 +298,6 @@ To avoid this issue, change your cluster timezone to UTC. == Additional resources -* For information about variable APIs, see xref:variables-api.adoc[Variable API reference] and visit the link:{{navprefix}}/restV2-playground?apiResourceId=http%2Fapi-endpoints%2Fvariable%2Fput-variable-values[REST API Playground]. +* For information about variable APIs, see xref:variables.adoc[Variable API reference] and visit the link:{{navprefix}}/restV2-playground?apiResourceId=http%2Fapi-endpoints%2Fvariable%2Fput-variable-values[REST API Playground]. * For more information about SQL passthrough functions, see link:https://docs.thoughtspot.com/cloud/latest/formula-reference#passthrough-functions[Formula function reference^]. * For information about the IANA timezone strings, see link:https://www.iana.org/time-zones[IANA Timezone Database^]. \ No newline at end of file diff --git a/modules/ROOT/pages/tml-api.adoc b/modules/ROOT/pages/tml-api.adoc index 3b90923c6..1ec8099f6 100644 --- a/modules/ROOT/pages/tml-api.adoc +++ b/modules/ROOT/pages/tml-api.adoc @@ -1,12 +1,13 @@ -= TML API += REST API v1 - TML API endpoints :toc: true :toclevels: 1 :page-title: TML Export and Import API -:page-pageid: tml-api +:page-pageid: tml-api-v1 :page-description: The TML API endpoints allow you to export and import TML files -The TML API endpoints allow you to programmatically export, validate, and import scriptable xref:tml.adoc[ThoughtSpot Modeling Language (TML), window=_blank] files. You can use these API endpoints to automate the change management and deployment processes between your development and production environments. With TML API, you can easily migrate your ThoughtSpot content from one environment to another by automating the entire change management process and thereby reducing the risk of human error. +include::{path}/rest-apiv1-deprecation-note.adoc[] + // [NOTE] // ==== @@ -14,6 +15,9 @@ The TML API endpoints allow you to programmatically export, validate, and import // ==== == Supported operations + +The TML API endpoints allow you to programmatically export, validate, and import scriptable xref:tml.adoc[ThoughtSpot Modeling Language (TML), window=_blank] files. You can use these API endpoints to automate the change management and deployment processes between your development and production environments. With TML API, you can easily migrate your ThoughtSpot content from one environment to another by automating the entire change management process and thereby reducing the risk of human error. + include::{path}/tml-api-list.adoc[] [#import] diff --git a/modules/ROOT/pages/tml-export.adoc b/modules/ROOT/pages/tml-export.adoc new file mode 100644 index 000000000..7bfd58583 --- /dev/null +++ b/modules/ROOT/pages/tml-export.adoc @@ -0,0 +1,101 @@ += Export TML +:toc: true +:toclevels: 2 + +:page-title: Export TML +:page-pageid: tml-export +:page-description: Export the TML representation of ThoughtSpot metadata objects via REST API +// SOURCE: SCAL-307283, SCAL-317357 + +[#export-tml] +To export the TML data, your account must have the `DATAMANAGEMENT` (Can manage data) or `ADMINISTRATION` (Can administer ThoughtSpot) privilege. + +The default format to export the objects is JSON. To export the TML representation of the metadata objects from ThoughtSpot in JSON or YAML format, use the following endpoint: + +* link:https://developers.thoughtspot.com/docs/restV2-playground?apiResourceId=http%2Fapi-endpoints%2Fmetadata%2Fexport-metadata-tml[**POST** /api/rest/2.0/metadata/tml/export] + +To export the TML representation of the metadata objects in a *batch*, use the following endpoint: + +* link:https://developers.thoughtspot.com/docs/restV2-playground?apiResourceId=http%2Fapi-endpoints%2Fmetadata%2Fexport-metadata-tml-batched[**POST** /api/rest/2.0/metadata/tml/export/batch] + +There are several export options available with these APIs: + +== Metadata specification for Answers +To export a specific metadata object, specify the name or ID of the object. + +For Answer objects, the `identifier` is optional, and you can define parameters such as `session_identifier` and `generation_number` instead. These attributes can be used to export unsaved Answers generated from Spotter queries or Answers that do not have the name and ID assigned. + +== Export associated objects + +To export associated objects, set the following attributes: + +* `export_associated` + +When set to `true`, exports the associated objects for the `export_ids` specified in the API request. The API exports any underlying Models, tables, or views for a given object. By default, the API does not export these underlying objects. +* `export_dependent` + +Specifies if the Tables of the referenced Connection object must be included in the export. +* `export_connection_as_dependent` + +Specifies if a Connection object must be included as a dependent object when exporting a Table, Model, Answer, or Liveboard TML. + +== Export FQNs + +When `export_fqn=true`, the API exports the FQNs of the referenced objects in the TML data. For example, if you are exporting a Liveboard and its associated objects, the API returns the Liveboard TML data with the FQNs of the referenced Model. +Note that the FQN of a referenced object is the same as the GUID of that object. + +ThoughtSpot recommends adding the fqn property before importing the TML objects into the system, because only the name of a referenced object is not sufficient to identify the referenced object during TML import. For example, if your ThoughtSpot instance has two Models with the same name, the TML import for a Liveboard that uses one of these Models would fail unless the Liveboard TML includes the FQN of the referenced object. +The `export_fqn` attribute is useful when ThoughtSpot has multiple objects with the same name and you want to eliminate ambiguity during TML import. The `export_fqn=true` property adds the FQNs of the referenced objects in the TML export API response and saves the manual effort of adding FQNs for TML import. + +// PORTED from tml-api.adoc (v1) lines 235-239 — was commented out on the v1 page; confirm why before publishing. +// RENAMED for v2: `force_create` -> `create_new`. Worksheet -> Model. +[NOTE] +==== +When you import multiple objects in bulk and create objects using the `create_new` attribute, the new object may refer to an existing object with the same FQN in the ThoughtSpot system instead of the other objects provided in the TML import request. For example, when you upload a TML representation of a Liveboard and the associated Model with the FQNs obtained from the TML export API, the imported Liveboard may refer to an existing Model with the same FQN in the ThoughtSpot system instead of the new Model created during the TML import. + +If you want the new objects created during the TML import to refer to the other associated objects created during the same import operation, set the `export_fqn` attribute to `false` during TML export or remove the FQNs manually before the TML import. +==== + +For more information about using FQNs during import, see xref:tml-import.adoc#import-tml[Import TML]. + +== Export schema + +Specifies the schema version to use during TML export. For link:https://docs.thoughtspot.com/cloud/latest/models[Models, window=_blank], set `export_schema_version` to v2. +The v1 schema is used for Worksheet objects (Deprecated). + +== Additional export options for REST API v2 +Following are some additional attributes which can be set for exporting objects: + +* `include_obj_id_ref` + +When set to `true`, exports the object ID of the referenced object. This flag will work only when the object ID feature is enabled. Contact ThoughtSpot Support to enable the feature. + +* `include_guid` + +When set to `true`, exports the guid of the object. This flag will work only when the object ID feature is enabled. Contact ThoughtSpot Support to enable the feature. +* `include_obj_id` + +When set to `true`, exports the object ID of the object. This flag will work only when the object ID feature is enabled. Contact ThoughtSpot Support to enable the feature. +* `export_with_associated_feedbacks` + +When set to `true`, exports the TML of an object along with all feedback, such as Spotter or Sage feedback, associated with that object. No feedback file will be exported if there are no feedback entries associated with the object +* `export_column_security_rules` [beta betaBackground]^Beta^ + +When set to `true`, exports the column-level security rules defined on the object. Contact ThoughtSpot Support to enable the feature. +* `export_with_column_aliases` [beta betaBackground]^Beta^ + +When set to `true`, export column aliases of the Model if the data Model includes any link:https://docs.thoughtspot.com/cloud/latest/column-aliases[column aliases, window=_blank]. + +== Export in a batch +This API operation supports exporting User, User Group, and Role objects only. +To export objects in a batch, set the following additional attributes: + +// PORTED from tml-api.adoc (v1) line 342-347 — parameter name and allowed values were undocumented here. +* `metadata_type` + +Type of the metadata object to export. Use one of the following values: `USER`, `USER_GROUP`, or `ROLE`. The `ROLE` value applies only to instances on which xref:roles.adoc[Role-based access control] is enabled. + +* `batch_size` + +Exports the specified number of objects in a single API request. A batch size of up to 200 objects is allowed for a single API operation. +// PORTED from tml-api.adoc (v1) line 340 — VERIFY FOR v2: v1 default was `20`. +The default batch size is 20. + +* `batch_offset` + +Offsets the API response by the specified number. Batch offset value defines the starting position of the records for the results returned by the API. +// PORTED from tml-api.adoc (v1) line 341 — VERIFY FOR v2: v1 default was `0`. +The default batch offset is 0. + +// PORTED from tml-api.adoc (v1) line 348 — batch-export semantics differ from the `export_dependent` documented under "Export associated objects" above. +* `export_dependent` + +Specifies if the dependent objects must be exported. For example, the user groups to which user objects are assigned, or the sub-groups of a user group. To get full details of the dependent objects, the API call initiator must have view or edit access to the dependent object. + +For more information, see the API documentation in REST API v2 Playground. diff --git a/modules/ROOT/pages/tml-import.adoc b/modules/ROOT/pages/tml-import.adoc new file mode 100644 index 000000000..ea1ae5f5e --- /dev/null +++ b/modules/ROOT/pages/tml-import.adoc @@ -0,0 +1,567 @@ += Import TML +:toc: true +:toclevels: 2 + +:page-title: Import TML +:page-pageid: tml-import +:page-description: Import the TML representation of ThoughtSpot metadata objects via REST API +// SOURCE: SCAL-307283, SCAL-317357 + +[NOTE] +==== +If using older versions of TML files for Liveboards, ensure that your TML file has the object name as `liveboard`. Replace any `pinboard` occurrences with `liveboard` before import. +==== + +[#import-tml] +To import a modified TML object, your account must have the `DATAMANAGEMENT` (*Can manage data*) or `ADMINISTRATION` (*Can administer ThoughtSpot*) privilege. + +You can import single or multiple objects using the `tml/import` API. If you are importing TML files one at a time, include the `fqn` property to distinguish objects that have the same name. If you have multiple connections or tables with the same name and the Connection or Table you reference in your TML does not have a unique name, it can lead to invalid object references. Adding `fqn` helps ThoughtSpot differentiate a Table from another with the same name. + +By default, the `fqn` parameter is not present in the TML file. However, you can xref:tml-export.adoc#_export_fqns[export TML with FQNs] and use it during the import. + +You can also set the `skip_diff_check` to `true` to skip diff check before processing TMLs for imports. This attribute helps identify the objects that haven’t been changed since the last import or TML update, and eliminates importing redundant objects. + +To import TML representation of the metadata objects into ThoughtSpot, use the following API endpoint: + +* +++POST /api/rest/2.0/metadata/tml/import+++ + +There are multiple kinds of imports possible: + +* `PARTIAL` imports all objects that validate successfully, and ignores objects that do not validate successfully. +* `ALL_OR_NONE` imports the objects that validate successfully. +* `VALIDATE_ONLY` validates the objects but does not import them. +* `PARTIAL_OBJECT` +imports objects that validate successfully and skips the objects that do not validate successfully. If the import fails for a visualization object in a Liveboard TML, the Liveboard will be imported without that visualization object. Similarly, if importing a relationship in a logical table fails, the table TML will be imported with warnings in the API response. + +You can also specify additional parameters to set the Org context and skip CDW validation checks for Table TMLs. + +[NOTE] +==== +If you import only a Model object, it may take some time for the Model to become available in the ThoughtSpot system. You may need to wait for a few seconds to create answers and Liveboards. + +However, if you import a Model along with Liveboards, answers, and other dependent objects in a single API call, the imported objects will be immediately available for use. +==== + +// PORTED from tml-api.adoc (v1) line 68 — was attached to the v1 `force_create` parameter. +// VERIFY FOR v2: v1 returned `id_guid` in the RESPONSE HEADERS. The v2 endpoint most likely +// returns the new GUID in the response body instead — confirm the property and location +// before publishing, or drop this note. +[NOTE] +==== +To know the GUID assigned to a new object created from the TML import, check the `id_guid` property in the response headers. +==== + +[#personalized-views-portability] +== Personalized Views portability + +Personalized Views support improved portability across ThoughtSpot environments. When importing a Personalized View TML set the `enable_personalized_view_upsert` to `true` in the API request to `POST /api/rest/2.0/metadata/tml/import`. ThoughtSpot then checks the target environment for an existing Personalized View with a matching `obj_id`. If a match is found, the import updates the existing view rather than creating a duplicate. If no match is found, a new Personalized View is created. + +To enable this feature for your instance, contact your ThoughtSpot administrator. + +Two new fields are added to the TML, make it easier to migrate Personalized Views between environments without creating duplicates. + +`author`::: +A new `author` field is added to the Personalized View TML during export. This field is used to delegate ownership to another user during import. + +`obj_id`::: +A new `obj_id` field provides stable cross-environment object identity for inter-Org deployments. Use the same `obj_id` value across environments to ensure consistent identity during migrations. + + + +=== Example for a Personalized View TML with Object ID + +[source,yaml] +---- + views: + - view_guid: ff83055b-a867-43e7-978e-106e907e1912 + obj_id: California-LT-ff83855b + name: California - LT + view_filters: + - column: + - Retail Sales - Classic::Store State + oper: in + values: + - California + is_public: false + author: + username: user1 + user_email: user1@thoughtspot.com +---- + +=== Limitation without this feature enabled + +ThoughtSpot's link:https://docs.thoughtspot.com/cloud/latest/personalized-liveboard-views[personalized Liveboard views] let users apply filters and save configurations as named views on a Liveboard. +In multi-environment deployments (for example, a Dev instance and a Prod instance), these user-saved views can be lost when a Liveboard is updated and re-imported using the xref:#import-tml[TML import API] or the UI *Import TML* option. +If the import is performed by an administrator account, all personalized views saved by end users are removed as part of this replacement. + +Why this happens?:: + +Personalized views are stored as user-owned objects linked to the Liveboard’s GUID. When an admin imports a Liveboard TML that matches an existing GUID, the import operation overwrites the Liveboard, and the associated user views are not carried forward. ++ +This happens because personalized views are created and usually owned by end users in a different environment (likely a Prod instance). They are not included in Liveboard TML files exported from a development or staging environment, so the import has no record of them. + +Workarounds:: +. Import as a non-admin user - ++ +The simplest workaround is to perform the final TML import in the production environment using a *non-admin user account* that has edit access to the Liveboard, rather than an admin account. +Because non-admin users do not have the authority to overwrite user-linked metadata during import, ThoughtSpot preserves the existing personalized views attached to the Liveboard. +. Embed existing saved views in the TML before import - ++ +You can export the current saved views from the production Liveboard, append them to the updated TML, and then import the combined TML. + +== Import TML objects asynchronously +The `metadata/tml/import` API imports TML objects synchronously. When you try to import large and complex metadata objects, the synchronous import operation takes more time to process data and sometimes can result in a timeout error. + +To allow mutually exclusive import tasks to run in parallel, process TML objects asynchronously, and check import task status, ThoughtSpot provides the following APIs: + +* +++POST /api/rest/2.0/metadata/tml/async/import+++ + +Creates an import TML tasks and processes TMLs asynchronously + +* +++POST /api/rest/2.0/metadata/tml/async/status+++ + +Fetches status of import tasks + + +=== Best practices for async TML import + +Use the following guidelines to configure and manage async TML import tasks effectively. + +==== Choose the right import policy + +[width="100%", cols="1,3,2,2"] +[options='header'] +|==== +|Policy|Behavior|Recommended use case|Limits and risks + +|`ALL_OR_NONE` +|All objects are validated and saved in a single database write. +If any object fails, no objects are written. +|Small, tightly coupled object sets requiring atomicity. +|Limit to approximately 50 TML objects per task. +Exceeding this risks OOM errors or database write failures. +Liveboard size affects this limit; Liveboards averaging approximately 30 visualizations are a useful sizing baseline. + +|`VALIDATE_ONLY` +|Objects are validated in memory. +No changes are written to the database. +|Pre-import validation before committing to a production import. +|All changes accumulate in memory. +Very large tasks risk OOM errors. + +|`PARTIAL` +|Objects that pass validation are written. +Failed objects are skipped without dropping subentities. +If a subentity (such as a visualization) fails, the parent object (such as a Liveboard) also fails and is not written. +|Large-scale migrations where some failures are expected. +Resubmit failed objects as a new task after fixing errors. +|Recommended policy for large imports. +Objects are written incrementally, reducing memory pressure. + +|`PARTIAL_OBJECT` +|Objects that pass validation are written. +If a subentity (visualization, join, or RLS rule) fails, the parent object is written with a warning and the failed subentity is dropped. +|Large-scale migrations where pipeline continuity matters more than completeness. +|Recommended when a missing visualization or dropped join is acceptable in the target environment. +|==== + +[NOTE] +==== +If you use custom scripts to batch imports with `ALL_OR_NONE`, the net result across batches is effectively the same as `PARTIAL` behavior—some batches succeed and some fail. +Use the `PARTIAL` policy directly for large-volume imports rather than scripting `ALL_OR_NONE` batches. +==== + +[IMPORTANT] +==== +Use `PARTIAL` or `PARTIAL_OBJECT` for large import operations. +`ALL_OR_NONE` and `VALIDATE_ONLY` process all objects in memory or in a single database transaction, which can cause OOM errors on large tasks. +==== + +==== Size your import tasks + +* For `ALL_OR_NONE` and `VALIDATE_ONLY`, limit tasks to approximately 50 TML objects. +There is no hard code limit, but larger tasks risk OOM errors or failed database writes. +The safe upper bound depends on Liveboard complexity. +Liveboards with an average of approximately 30 visualizations each provide a reasonable sizing baseline. + +* For `PARTIAL` and `PARTIAL_OBJECT`, there is no per-task object limit enforced by the API. +These policies write objects incrementally and are appropriate for large migration workloads. + +* The API payload size limit is 500 MB per request (infrastructure limit). +Contact ThoughtSpot Support if your use case requires a larger limit. + + +==== Avoid parallel imports of the same object + +Never submit tasks that include the same object in more than one active task simultaneously. +Concurrent writes to the same object cause a version conflict, and one of the tasks will fail. + +Design your import pipeline so that each object appears in at most one active import task at a time. +Sequence tasks, do not parallelize them across the same objects. + +==== Monitor the task queue and status + +The async import queue supports a maximum of 100 concurrent tasks. +Submitting more than 100 tasks at once causes the excess tasks to be rejected with a `FAILED` status immediately. + +Poll the `POST /api/rest/2.0/metadata/tml/async/status` endpoint to check task status. + +[width="100%", cols="1,4"] +[options='header'] +|==== +|Status value|Description + +|`IN_QUEUE` +|The task is waiting to be processed. +The queue limit is 100 concurrent tasks. +Tasks submitted beyond the limit are rejected immediately with status `FAILED`. + +|`IN_PROGRESS` +|The task is being processed. + +|`COMPLETED` +|The task processing is complete. +`COMPLETED` does not mean every object imported successfully. +Individual objects within the task have their own statuses. +Inspect per-object status in the response to identify failures. + +|`FAILED` +|The task failed. +This could be due to multiple reasons such as - the queue was full at submission time, a policy-level failure occurred, or an unrecoverable error was encountered during processing. +|==== + +*Recommended polling intervals:* + +The status API enforces a rate limit of 100 requests per minute. +Exceeding this limit returns an error. + +For practical use: + +* For small tasks, poll no more frequently than every 30 seconds. +* For large tasks, a polling interval of 1 minute is recommended, as larger tasks take proportionally longer to complete. + +==== Use API parameters correctly + +The following parameters in `POST /api/rest/2.0/metadata/tml/async/import` require careful use: + +`create_new`:: +Set `create_new: true` only when you want to create objects with new GUIDs, not update existing objects. +Setting this parameter on objects that already exist creates duplicates. +Do not set this parameter unless you are certain that new objects should be created. + +`skip_diff_check`:: +Set `skip_diff_check: true` only when you want to force a re-import of a TML file that has not changed since the previous import. +By default, ThoughtSpot identifies unchanged objects and skips them to reduce import time. +Enable this parameter only when unchanged files must be explicitly reprocessed. + +`enable_large_metadata_validation`:: +Set to `true` if the database contains multiple thousands of tables. +When enabled, ThoughtSpot validates schema one table at a time, which helps circumvent metadata fetching limitations of the Cloud Data Warehouse (CDW). +Default: `false`. + +`enable_personalized_view_upsert`:: +Set to `true` to enable update and insert of personalized views in a Liveboard during TML import. +When enabled, personalized views are preserved or created as part of the import operation instead of being discarded. +Default: `false`. + + +==== Schedule large imports during off-peak hours + +Large TML migrations can temporarily increase system resource usage. +Schedule bulk async imports during off-peak hours to reduce the risk of impacting users who are actively using the cluster. + + +=== Schedule import tasks + +You can import TML objects asynchronously by scheduling TML import tasks via `POST` request to POST `/api/rest/2.0/metadata/tml/async/import` API endpoint. You can send the following parameters in the API request body: + +[width="100%" cols="2,4,1"] +[options='header'] +|==== +|Form parameter|Description| Default +|`metadata_tmls` |__Array of strings__. Array of the TML strings. |__None__ +|`create_new` + +__Optional__ |__Boolean__. To create TML objects with new GUIDs during import, specify `true`. By default, ThoughtSpot updates the existing objects that have the same GUID as the objects you are importing. | `false` +|`all_orgs_context` + +__Optional__ |__Boolean__. Specify if import operation must be run for all Orgs on your instance. + +__Requires Org administration privileges to access TML objects across all Orgs.__| `false` + +|`import_policy` a|__String__. Policy to follow during import. The allowed values are: + +* `PARTIAL` +//Imports objects that validate successfully. Skips the objects that do not validate successfully and their dependent objects if any. +* `ALL_OR_NONE` +//Imports all objects that validate successfully. If the import fails for one object, no objects will be imported. +* `VALIDATE_ONLY` +//Validates the objects but does not import them. +* `PARTIAL_OBJECT` +//Imports objects that validate successfully and skips the objects that do not validate successfully. If the import fails for a visualization object in a Liveboard TML, the Liveboard will be imported without that visualization object. Similarly, if importing a relationship in a logical table fails, the table TML will be imported with warnings in the API response. +| `PARTIAL_OBJECT` + +|`skip_diff_check` + +__Optional__ +|__Boolean__ |`false` +|`enable_large_metadata_validation` + +__Optional__ +|__Boolean__ +|`false` +|`enable_personalized_view_upsert` + +__Optional__ +|__Boolean__ +|`false` +|==== + +==== Example request + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-host}/api/rest/2.0/metadata/tml/async/import' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "metadata_tmls": [ + "{\\\"guid\\\": \\\"2ed8192a-1e9d-47d1-810d-52b14cb0e9fe\\\",\\\"liveboard\\\": {\\\"name\\\": \\\"Total Sales\\\",\\\"visualizations\\\": [{\\\"id\\\": \\\"Viz_1\\\",\\\"answer\\\": {\\\"name\\\": \\\"Total quantity purchased, Total sales by region\\\",\\\"description\\\": \\\"test\\\",\\\"tables\\\": [{\\\"id\\\": \\\"(Sample) Retail - Apparel\\\",\\\"name\\\": \\\"(Sample) Retail - Apparel\\\"}],\\\"search_query\\\": \\\"[region] [quantity purchased] [sales]\\\",\\\"answer_columns\\\": [{\\\"name\\\": \\\"Total quantity purchased\\\"},{\\\"name\\\": \\\"Total sales\\\"},{\\\"name\\\": \\\"region\\\"}],\\\"table\\\": {\\\"table_columns\\\": [{\\\"column_id\\\": \\\"Total quantity purchased\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"Total sales\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"region\\\",\\\"show_headline\\\": false}],\\\"ordered_column_ids\\\": [\\\"region\\\",\\\"Total quantity purchased\\\",\\\"Total sales\\\"],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"tableVizPropVersion\\\\\\\": \\\\\\\"V1\\\\\\\"}\\\"},\\\"chart\\\": {\\\"type\\\": \\\"COLUMN\\\",\\\"chart_columns\\\": [{\\\"column_id\\\": \\\"Total quantity purchased\\\"},{\\\"column_id\\\": \\\"Total sales\\\"},{\\\"column_id\\\": \\\"region\\\"}],\\\"axis_configs\\\": [{\\\"x\\\": [\\\"region\\\"],\\\"y\\\": [\\\"Total quantity purchased\\\",\\\"Total sales\\\"]}],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"version\\\\\\\": \\\\\\\"V4DOT2\\\\\\\",\\\\\\\"chartProperties\\\\\\\": {\\\\\\\"responsiveLayoutPreference\\\\\\\": \\\\\\\"AUTO_ON\\\\\\\",\\\\\\\"chartSpecific\\\\\\\": {}},\\\\\\\"axisProperties\\\\\\\": [{\\\\\\\"id\\\\\\\": \\\\\\\"f6701821-5630-49cd-b26f-f98bebb4e98e\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"Y\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Total quantity purchased\\\\\\\"],\\\\\\\"isOpposite\\\\\\\": false}},{\\\\\\\"id\\\\\\\": \\\\\\\"1e086aef-236d-4cf0-8909-9e04e04a1ac4\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"Y\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Total sales\\\\\\\"],\\\\\\\"isOpposite\\\\\\\": true}},{\\\\\\\"id\\\\\\\": \\\\\\\"7be648d3-c791-43e4-bb13-63fea808f326\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"X\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"region\\\\\\\"]}}],\\\\\\\"systemSeriesColors\\\\\\\": [{\\\\\\\"serieName\\\\\\\": \\\\\\\"Total quantity purchased\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#48D1E0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"Total sales\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2E75F0\\\\\\\"}]}\\\"},\\\"display_mode\\\": \\\"CHART_MODE\\\"},\\\"viz_guid\\\": \\\"b8b38851-5980-40a1-bd88-608b7a9c6e86\\\"},{\\\"id\\\": \\\"Viz_2\\\",\\\"answer\\\": {\\\"name\\\": \\\"Total sales in a year\\\",\\\"tables\\\": [{\\\"id\\\": \\\"(Sample) Retail - Apparel\\\",\\\"name\\\": \\\"(Sample) Retail - Apparel\\\"}],\\\"search_query\\\": \\\"[sales] [store] [date].monthly [date].'\''this year'\''\\\",\\\"answer_columns\\\": [{\\\"name\\\": \\\"Month(date)\\\"},{\\\"name\\\": \\\"Total sales\\\"},{\\\"name\\\": \\\"store\\\"}],\\\"table\\\": {\\\"table_columns\\\": [{\\\"column_id\\\": \\\"Month(date)\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"Total sales\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"store\\\",\\\"show_headline\\\": false}],\\\"ordered_column_ids\\\": [\\\"store\\\",\\\"Month(date)\\\",\\\"Total sales\\\"],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"tableVizPropVersion\\\\\\\": \\\\\\\"V1\\\\\\\"}\\\"},\\\"chart\\\": {\\\"type\\\": \\\"LINE\\\",\\\"chart_columns\\\": [{\\\"column_id\\\": \\\"Month(date)\\\"},{\\\"column_id\\\": \\\"Total sales\\\"},{\\\"column_id\\\": \\\"store\\\"}],\\\"axis_configs\\\": [{\\\"x\\\": [\\\"Month(date)\\\"],\\\"y\\\": [\\\"Total sales\\\"],\\\"color\\\": [\\\"store\\\"]}],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"version\\\\\\\": \\\\\\\"V4DOT2\\\\\\\",\\\\\\\"chartProperties\\\\\\\": {\\\\\\\"responsiveLayoutPreference\\\\\\\": \\\\\\\"AUTO_ON\\\\\\\",\\\\\\\"chartSpecific\\\\\\\": {}},\\\\\\\"axisProperties\\\\\\\": [{\\\\\\\"id\\\\\\\": \\\\\\\"feb33c4a-614b-4623-9d12-1c4cf2250801\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"Y\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Total sales\\\\\\\"],\\\\\\\"isOpposite\\\\\\\": false}},{\\\\\\\"id\\\\\\\": \\\\\\\"e89293cb-d10a-40d5-b787-81be33cc8b81\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"X\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Month(date)\\\\\\\"]}}],\\\\\\\"systemSeriesColors\\\\\\\": [{\\\\\\\"serieName\\\\\\\": \\\\\\\"6a4acb32-9036-4d4c-a830-f2b06966a322\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#48D1E0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"39e5242e-43d0-4ef7-8673-73b12433e0c5\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2E75F0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"arizona (85226)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2E75F0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"arizona (86001)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#48D1E0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"california (91006)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FCC838\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"california (94702)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#06BF7F\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"colorado (80301)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#8C62F5\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"colorado (80920)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FF8142\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"connecticut (06110)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#ABC7F9\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"connecticut (06854)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#B5ECF2\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"delaware (19702)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FDE9AF\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"georgia (30022)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#9BE5CB\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"georgia (30329)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#D1C0FB\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"idaho (83704)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FFCCB3\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"illinois (60062)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2359B6\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"illinois (60642)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#369FAA\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"indiana (46250)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#BF982A\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"iowa (50266)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#049160\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"maryland (21045)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#6A4ABA\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"massachusetts (01701)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#C26232\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"massachusetts (02215)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#71A1F4\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"michigan (48103)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#82DFE9\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"michigan (49512)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FCD977\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"minnesota (55369)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#56D3A8\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"minnesota (55420)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#B094F8\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"missouri (63144)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FFA97E\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"montana (59106)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#163772\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"montana (59718)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#22636B\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"nevada (89052)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#785F1A\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"nevada (89145)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#025B3C\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"new hampshire (03860)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#422E75\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"new jersey (07936)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#7A3D1F\\\\\\\"}]}\\\"},\\\"display_mode\\\": \\\"CHART_MODE\\\"},\\\"viz_guid\\\": \\\"7efc7b0e-e680-44a4-ba9c-3bd5d7272367\\\"},{\\\"id\\\": \\\"Viz_3\\\",\\\"answer\\\": {\\\"name\\\": \\\"Total sales by item type and region\\\",\\\"tables\\\": [{\\\"id\\\": \\\"(Sample) Retail - Apparel\\\",\\\"name\\\": \\\"(Sample) Retail - Apparel\\\"}],\\\"search_query\\\": \\\"[sales] [item type] [region]\\\",\\\"answer_columns\\\": [{\\\"name\\\": \\\"Total sales\\\"},{\\\"name\\\": \\\"item type\\\"},{\\\"name\\\": \\\"region\\\"}],\\\"table\\\": {\\\"table_columns\\\": [{\\\"column_id\\\": \\\"Total sales\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"item type\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"region\\\",\\\"show_headline\\\": false}],\\\"ordered_column_ids\\\": [\\\"item type\\\",\\\"region\\\",\\\"Total sales\\\"],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"tableVizPropVersion\\\\\\\": \\\\\\\"V1\\\\\\\"}\\\"},\\\"chart\\\": {\\\"type\\\": \\\"STACKED_COLUMN\\\",\\\"chart_columns\\\": [{\\\"column_id\\\": \\\"Total sales\\\"},{\\\"column_id\\\": \\\"item type\\\"},{\\\"column_id\\\": \\\"region\\\"}],\\\"axis_configs\\\": [{\\\"x\\\": [\\\"item type\\\"],\\\"y\\\": [\\\"Total sales\\\"],\\\"color\\\": [\\\"region\\\"]}],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"version\\\\\\\": \\\\\\\"V4DOT2\\\\\\\",\\\\\\\"chartProperties\\\\\\\": {\\\\\\\"responsiveLayoutPreference\\\\\\\": \\\\\\\"AUTO_ON\\\\\\\",\\\\\\\"chartSpecific\\\\\\\": {}},\\\\\\\"axisProperties\\\\\\\": [{\\\\\\\"id\\\\\\\": \\\\\\\"a330db6d-3714-4b5f-aed7-cca5ab679502\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"Y\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Total sales\\\\\\\"],\\\\\\\"isOpposite\\\\\\\": false}},{\\\\\\\"id\\\\\\\": \\\\\\\"96ac1ce3-7efd-455e-a569-2cd0792b5f95\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"X\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"item type\\\\\\\"]}}],\\\\\\\"systemSeriesColors\\\\\\\": [{\\\\\\\"serieName\\\\\\\": \\\\\\\"Total sales\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#48D1E0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"92153012-664c-458e-9a74-6138c5030838\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2E75F0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"east\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#06BF7F\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"midwest\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FCC838\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"south\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#48D1E0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"southwest\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#71A1F4\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"west\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2E75F0\\\\\\\"}]}\\\"},\\\"display_mode\\\": \\\"CHART_MODE\\\"},\\\"viz_guid\\\": \\\"9de47a0e-6f20-40ba-9a52-3374ee530f09\\\"},{\\\"id\\\": \\\"Viz_4\\\",\\\"answer\\\": {\\\"name\\\": \\\"Total sales by state\\\",\\\"tables\\\": [{\\\"id\\\": \\\"(Sample) Retail - Apparel\\\",\\\"name\\\": \\\"(Sample) Retail - Apparel\\\"}],\\\"search_query\\\": \\\"[state] [store] [sales]\\\",\\\"answer_columns\\\": [{\\\"name\\\": \\\"Total sales\\\"},{\\\"name\\\": \\\"state\\\"},{\\\"name\\\": \\\"store\\\"}],\\\"table\\\": {\\\"table_columns\\\": [{\\\"column_id\\\": \\\"Total sales\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"state\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"store\\\",\\\"show_headline\\\": false}],\\\"ordered_column_ids\\\": [\\\"state\\\",\\\"store\\\",\\\"Total sales\\\"],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"tableVizPropVersion\\\\\\\": \\\\\\\"V1\\\\\\\"}\\\"},\\\"chart\\\": {\\\"type\\\": \\\"GEO_AREA\\\",\\\"chart_columns\\\": [{\\\"column_id\\\": \\\"Total sales\\\"},{\\\"column_id\\\": \\\"state\\\"},{\\\"column_id\\\": \\\"store\\\"}],\\\"axis_configs\\\": [{\\\"x\\\": [\\\"state\\\"],\\\"y\\\": [\\\"Total sales\\\"]}],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"version\\\\\\\": \\\\\\\"V4DOT2\\\\\\\",\\\\\\\"chartProperties\\\\\\\": {\\\\\\\"chartSpecific\\\\\\\": {}},\\\\\\\"axisProperties\\\\\\\": [{\\\\\\\"id\\\\\\\": \\\\\\\"e4943da4-f159-470c-836b-7c6c55d59c2f\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"Y\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Total sales\\\\\\\"],\\\\\\\"isOpposite\\\\\\\": false}},{\\\\\\\"id\\\\\\\": \\\\\\\"b99d582a-b215-4381-89ad-280c451979e3\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"X\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"state\\\\\\\"]}}],\\\\\\\"systemMultiColorSeriesColors\\\\\\\": [{\\\\\\\"serieName\\\\\\\": \\\\\\\"Total sales\\\\\\\",\\\\\\\"colorMap\\\\\\\": [{\\\\\\\"serieName\\\\\\\": \\\\\\\"state\\\\\\\",\\\\\\\"color\\\\\\\": [\\\\\\\"#ffffb2\\\\\\\",\\\\\\\"#fddd87\\\\\\\",\\\\\\\"#fba35d\\\\\\\",\\\\\\\"#f75534\\\\\\\",\\\\\\\"#f9140a\\\\\\\",\\\\\\\"#d70315\\\\\\\",\\\\\\\"#b10026\\\\\\\"]}]}]}\\\"},\\\"display_mode\\\": \\\"CHART_MODE\\\"},\\\"viz_guid\\\": \\\"4ab1ed61-2930-46d4-af6f-778279d7414a\\\"}],\\\"filters\\\": [{\\\"column\\\": [\\\"region\\\"],\\\"oper\\\": \\\"in\\\",\\\"values\\\": [\\\"Midwest\\\"],\\\"is_mandatory\\\": false,\\\"is_single_value\\\": false,\\\"display_name\\\": \\\"region\\\"}],\\\"layout\\\": {\\\"tabs\\\": [{\\\"name\\\": \\\"Tab 1\\\",\\\"description\\\": \\\"\\\",\\\"tiles\\\": [{\\\"visualization_id\\\": \\\"Viz_1\\\",\\\"x\\\": 0,\\\"y\\\": 0,\\\"height\\\": 8,\\\"width\\\": 6},{\\\"visualization_id\\\": \\\"Viz_4\\\",\\\"x\\\": 6,\\\"y\\\": 0,\\\"height\\\": 8,\\\"width\\\": 6}],\\\"id\\\": \\\"2c4014b5-a606-4639-8ad0-01032ff3fc13\\\"},{\\\"name\\\": \\\"Tab 2\\\",\\\"description\\\": \\\"\\\",\\\"tiles\\\": [{\\\"visualization_id\\\": \\\"Viz_2\\\",\\\"x\\\": 0,\\\"y\\\": 0,\\\"height\\\": 8,\\\"width\\\": 6},{\\\"visualization_id\\\": \\\"Viz_3\\\",\\\"x\\\": 6,\\\"y\\\": 0,\\\"height\\\": 8,\\\"width\\\": 6}],\\\"id\\\": \\\"185b4875-e7c5-43d2-a9bc-0a404107a3ec\\\"}]}}}\", \"info\": { \"filename\": \"Copy of Total Sales.liveboard.tml\", \"name\": \"Copy of Total Sales\", \"id\": \"2ed8192a-1e9d-47d1-810d-52b14cb0e9fe\", \"type\": \"liveboard\", \"status\": { \"status_code\": \"OK\" } }" + ], + "create_new": true, + "all_orgs_context": false, +}' +---- + +==== Example response + +If the API request is successful, ThoughtSpot schedules an import task, and returns the task name and ID in the API response: + +[source,JSON] +---- +{ + "tenant_id": "default-tenant-id", + "org_id": 0, + "task_id": "075c322f-b000-4776-9c44-89e13420980c", + "task_name": "ASYNC_TML_26:Nov:2024-06:06:24", + "import_response": null, + "task_status": "IN_QUEUE", + "author_id": "08c6b203-ff6e-4ed8-b923-35ebbbfef27b", + "import_policy": "PARTIAL_OBJECT", + "created_at": null, + "in_progress_at": null, + "completed_at": null, + "total_object_count": 2, + "object_processed_count": null, + "modified_at": null, + "author_display_name": "UserA" +} +---- + +===== Response codes + +[options="header", cols="1,4"] +|==== +|HTTP status code|Description +|**200**|Async TML Import Task submitted successfully +|**400**|Invalid request +|**401**|Unauthorized access +|**403**|Forbidden access +|**500**|Unexpected Error +|==== + +=== Fetch status of the TML import task + +To fetch the status of a scheduled import task, send a `POST` request to the `POST /api/rest/2.0/metadata/tml/async/status` API endpoint. + +In the request body, include the following attributes: + +[width="100%" cols="2,4,1"] +[options='header'] +|==== +|Form parameter|Description| Default +|`task_ids` |__Array of strings__. Task IDs assigned to the scheduled TML async import operations. | __None__ +| `task_status` | __Array of strings__. Status of the scheduled import tasks to filter on. The following options are available: + + +* `COMPLETED` + +* `IN_QUEUE` + +* `IN_PROGRESS` + +* `FAILED` +| __None__ +|`author_identifier` + +__Optional__ |__String__. GUID of the author who initiated the import request. | __None__ +|`include_import_response` + +__Optional__ |__Boolean__. Specify whether to include import response in the task status objects.| `false` +|`record_offset` + +__Optional__ |__Integer__. The offset point, starting from where the task status should +be included in the response. | `0` +|`record_size` + +__Optional__ a|__Integer__. The number of task statuses to include in the +response starting from offset position. + +[NOTE] +==== +The maximum limit for the `record_size` that user can pass in an API request is 50. If the `record_size` exceeds this threshold, the API returns a bad request error. To extend the `record_size` limit, contact ThoughtSpot Support. +==== +| `5` + +|==== + +[IMPORTANT] +==== +You can poll up to 100 API requests per minute to get details of your TML import tasks. The API returns an error if you exceed this rate limit. +==== + +==== Example request + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-host}/api/rest/2.0/metadata/tml/async/status' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "record_offset": 0, + "record_size": 5, + "include_import_response": true, + "task_ids": [ + "c8c8c4da-0bc8-4460-8039-cfa7fd598335" + ], + "task_status": [ + "COMPLETED" + ], + "author_identifier": "95ac814f-eb01-4625-93c7-c7624b29d226" +}' +---- + +==== Example response + +If the API request is successful, ThoughtSpot returns the status details of the TML async import tasks. +If Orgs are enabled on your instance, the API returns task status only for objects within the current Org context. + +[source,JSON] +---- +{ + "status_list": [ + { + "tenant_id": "default-tenant-id", + "org_id": 0, + "task_id": "c8c8c4da-0bc8-4460-8039-cfa7fd598335", + "task_name": "ASYNC_TML_26:Nov:2024-06:06:24", + "import_response": { + "object": [ + { + "filename": "tml_0", + "zip_filename": "zip_tml_0", + "response": { + "status": { + "status_code": "ERROR", + "error_message": "Invalid YAML/JSON syntax in file." + } + }, + "request_index": 0 + }, + { + "filename": "tml_1", + "zip_filename": "zip_tml_1", + "response": { + "status": { + "status_code": "ERROR", + "error_message": "Invalid YAML/JSON syntax in file." + } + }, + "request_index": 1 + } + ], + "status": { + "status_code": "OK", + "error_code": 0, + "error_message": "" + } + }, + "task_status": "COMPLETED", + "author_id": "08c6b203-ff6e-4ed8-b923-35ebbbfef27b", + "import_policy": "PARTIAL_OBJECT", + "created_at": 1732601184212, + "in_progress_at": 1732601184255, + "completed_at": 1732601184476, + "total_object_count": 2, + "object_processed_count": 2, + "modified_at": 1732601184476, + "author_display_name": "UserA" + } + ], + "last_batch": true +} +---- + +===== Response codes + +[options="header", cols="1,4"] +|==== +|HTTP status code|Description +|**200**|Async TML import task status fetched successfully +|**400**|Invalid request +|**401**|Unauthorized access +|**403**|Forbidden access +|**500**|Unexpected Error +|==== + +[#yamlReimport] +== YAML reimport in REST API v2 Playground +If you are using the REST API Playground to import TML in YAML format, note that copying YAML content directly in the input field will likely result in the `Invalid YAML/JSON syntax in file` error. +When you copy the YAML output from the export TML API response in the Playground, the copied content is wrapped in quotation marks and include escaped newline characters (`\n`). When you paste this content directly in the `metadata_tml` input field, the API Playground double-escapes characters or removes necessary newline (`\n`) characters. Due to improper formatting, the YAML input becomes invalid for import, resulting in the `Invalid YAML/JSON syntax in file` error. + +To work around this issue, follow these steps: + +. After you +++export TML+++ in the Playground, use the `copy to clipboard` option to copy the YAML output from the API response as shown in this video. + ++ + +[div videoContainer] +-- +video::./images/tml-export.mp4[width=100%,options="autoplay,loop"] +-- ++ +The output copied from the API response is enclosed in quotation marks (`"`). +For example, `"guid: a162289a-c1ab-427e-9985-8fb5f7c7e539\nliveboard:\n name: Liveboard 1\n"`. +. Paste the YAML output copied from the export TML API response into a text editor. +. Remove the quotation marks, update the TML, and ensure that the YAML is properly formatted: + +`guid: a162289a-c1ab-427e-9985-8fb5f7c7e539\nliveboard:\n name: Liveboard 1\n` +. When +++importing TML in the Playground+++, do not paste the YAML directly into the `metadata_tmls` input field. Instead, use the JSON editor to add the YAML. +. To open the JSON editor, click *View JSON*. + +In the JSON preview, you'll see the following code: ++ +[source,JSON] +---- +{ + "metadata_tmls": [ + "metadata_tmls3", + "metadata_tmls5", + ], + "import_policy": "PARTIAL", + "create_new": false, + "all_orgs_context": false +} +---- +. Remove the text in the `metadata_tmls` array and paste your YAML content inside the array. If you are importing more than one TML, use a comma after pasting a TML YAML and then add YAML for the other TML. ++ +[source,JSON] +---- +{ + "metadata_tmls": [ + "guid: a162289a-c1ab-427e-9985-8fb5f7c7e539\nliveboard:\n name: Liveboard 1\n" + ], + "import_policy": "PARTIAL", + "create_new": false, + "all_orgs_context": false +} +---- ++ +You may see double-escaped characters in JSON preview. For example, `\\n` instead `\n`. However, these will not be imported in the actual payload. +. To submit the request, click **Try it Out**. + ++ +In the following video, you can see that pasting YAML directly in the `metadata_tmls` form field results in an error due to additional quotation marks and improper formatting. Using the JSON editor, you can paste the YAML inside the array and import TML successfully. ++ + +[div videoContainer] +-- +video::./images/import-tml.mp4[width=100%,options="autoplay,loop"] +-- diff --git a/modules/ROOT/pages/tml.adoc b/modules/ROOT/pages/tml.adoc index 424962b90..aba737cd2 100644 --- a/modules/ROOT/pages/tml.adoc +++ b/modules/ROOT/pages/tml.adoc @@ -44,570 +44,17 @@ Worksheets are deprecated in ThoughtSpot and replaced by Models. The TML API endpoints allow you to programmatically export, validate, and import scriptable TML files. You can use these API endpoints to automate the change management and deployment processes between your development and production environments. With TML API, you can easily migrate your ThoughtSpot content from one environment to another by automating the entire change management process and thereby reducing the risk of human error. -[NOTE] -==== -If using older versions of TML files for Liveboards, ensure that your TML file has the object name as `liveboard`. Replace any `pinboard` occurrences with `liveboard` before import. -==== - -== Import TML -To import a modified TML object, your account must have the `DATAMANAGEMENT` (*Can manage data*) or `ADMINISTRATION` (*Can administer ThoughtSpot*) privilege. - -You can import single or multiple objects using the `tml/import` API. If you are importing TML files one at a time, include the `fqn` property to distinguish objects that have the same name. If you have multiple connections or tables with the same name and the Connection or Table you reference in your TML does not have a unique name, it can lead to invalid object references. Adding `fqn` helps ThoughtSpot differentiate a Table from another with the same name. - -By default, the `fqn` parameter is not present in the TML file. However, you can export TML with FQNs and use it during the import. - -You can also set the `skip_diff_check` to `true` to skip diff check before processing TMLs for imports. This attribute helps identify the objects that haven’t been changed since the last import or TML update, and eliminates importing redundant objects. - -To import TML representation of the metadata objects into ThoughtSpot, use one of the following API endpoints: - -* +++POST /api/rest/2.0/metadata/tml/import+++ (REST API v2) -* xref:tml-api.adoc#import[POST /tspublic/v1/metadata/tml/import] (REST API v1) - -//While the v1 API accepts a string containing a JSON array of TML objects to upload, in YAML or JSON format, the v2 accepts it only in the JSON format. -[NOTE] -==== -If you import only a Model object, it may take some time for the Model to become available in the ThoughtSpot system. You may need to wait for a few seconds to create answers and Liveboards. - -However, if you import a Model along with Liveboards, answers, and other dependent objects in a single API call, the imported objects will be immediately available for use. -==== - -[#personalized-views-portability] -=== Personalized Views portability [earlyAccess eaBackground]#Early Access# - -Personalized Views support improved portability across ThoughtSpot environments. When importing a Personalized View TML set the `enable_personalized_view_upsert` to `true` in the API request to `POST /api/rest/2.0/metadata/tml/import`. ThoughtSpot then checks the target environment for an existing Personalized View with a matching `obj_id`. If a match is found, the import updates the existing view rather than creating a duplicate. If no match is found, a new Personalized View is created. - -To enable this feature for your instance, contact your ThoughtSpot administrator. - -Two new fields are added to the TML, make it easier to migrate Personalized Views between environments without creating duplicates. - -`author`::: -A new `author` field is added to the Personalized View TML during export. This field is used to delegate ownership to another user during import. - -`obj_id`::: -A new `obj_id` field provides stable cross-environment object identity for inter-Org deployments. Use the same `obj_id` value across environments to ensure consistent identity during migrations. - - - -==== Example for a Personalized View TML with Object ID - -[source,yaml] ----- - views: - - view_guid: ff83055b-a867-43e7-978e-106e907e1912 - obj_id: California-LT-ff83855b - name: California - LT - view_filters: - - column: - - Retail Sales - Classic::Store State - oper: in - values: - - California - is_public: false - author: - username: user1 - user_email: user1@thoughtspot.com ----- - -==== Limitation without this feature enabled - -ThoughtSpot's link:https://docs.thoughtspot.com/cloud/latest/personalized-liveboard-views[personalized Liveboard views] let users apply filters and save configurations as named views on a Liveboard. -In multi-environment deployments (for example, a Dev instance and a Prod instance), these user-saved views can be lost when a Liveboard is updated and re-imported using the xref:tml.adoc[TML import API] or the UI *Import TML* option. -If the import is performed by an administrator account, all personalized views saved by end users are removed as part of this replacement. - -Why this happens?:: - -Personalized views are stored as user-owned objects linked to the Liveboard’s GUID. When an admin imports a Liveboard TML that matches an existing GUID, the import operation overwrites the Liveboard, and the associated user views are not carried forward. -+ -This happens because personalized views are created and usually owned by end users in a different environment (likely a Prod instance). They are not included in Liveboard TML files exported from a development or staging environment, so the import has no record of them. - -Workarounds:: -. Import as a non-admin user - -+ -The simplest workaround is to perform the final TML import in the production environment using a *non-admin user account* that has edit access to the Liveboard, rather than an admin account. -Because non-admin users do not have the authority to overwrite user-linked metadata during import, ThoughtSpot preserves the existing personalized views attached to the Liveboard. -. Embed existing saved views in the TML before import - -+ -You can export the current saved views from the production Liveboard, append them to the updated TML, and then import the combined TML. - -== Import TML objects asynchronously -The REST v1 and v2 `metadata/tml/import` APIs import TML objects synchronously. When you try to import large and complex metadata objects, the synchronous import operation takes more time to process data and sometimes can result in a timeout error. - -To allow mutually exclusive import tasks to run in parallel, process TML objects asynchronously, and check import task status, ThoughtSpot provides the following APIs: - -* +++POST /api/rest/2.0/metadata/tml/async/import+++ + -Creates an import TML tasks and processes TMLs asynchronously - -* +++POST /api/rest/2.0/metadata/tml/async/status+++ + -Fetches status of import tasks - -=== Best practices for async TML import - -Use the following guidelines to configure and manage async TML import tasks effectively. - -==== Choose the right import policy - -[width="100%", cols="1,3,2,2"] -[options='header'] -|==== -|Policy|Behavior|Recommended use case|Limits and risks - -|`ALL_OR_NONE` -|All objects are validated and saved in a single database write. -If any object fails, no objects are written. -|Small, tightly coupled object sets requiring atomicity. -|Limit to approximately 50 TML objects per task. -Exceeding this risks OOM errors or database write failures. -Liveboard size affects this limit; Liveboards averaging approximately 30 visualizations are a useful sizing baseline. - -|`VALIDATE_ONLY` -|Objects are validated in memory. -No changes are written to the database. -|Pre-import validation before committing to a production import. -|All changes accumulate in memory. -Very large tasks risk OOM errors. - -|`PARTIAL` -|Objects that pass validation are written. -Failed objects are skipped without dropping subentities. -If a subentity (such as a visualization) fails, the parent object (such as a Liveboard) also fails and is not written. -|Large-scale migrations where some failures are expected. -Resubmit failed objects as a new task after fixing errors. -|Recommended policy for large imports. -Objects are written incrementally, reducing memory pressure. - -|`PARTIAL_OBJECT` -|Objects that pass validation are written. -If a subentity (visualization, join, or RLS rule) fails, the parent object is written with a warning and the failed subentity is dropped. -|Large-scale migrations where pipeline continuity matters more than completeness. -|Recommended when a missing visualization or dropped join is acceptable in the target environment. -|==== - -[NOTE] -==== -If you use custom scripts to batch imports with `ALL_OR_NONE`, the net result across batches is effectively the same as `PARTIAL` behavior—some batches succeed and some fail. -Use the `PARTIAL` policy directly for large-volume imports rather than scripting `ALL_OR_NONE` batches. -==== - -[IMPORTANT] -==== -Use `PARTIAL` or `PARTIAL_OBJECT` for large import operations. -`ALL_OR_NONE` and `VALIDATE_ONLY` process all objects in memory or in a single database transaction, which can cause OOM errors on large tasks. -==== - -==== Size your import tasks - -* For `ALL_OR_NONE` and `VALIDATE_ONLY`, limit tasks to approximately 50 TML objects. -There is no hard code limit, but larger tasks risk OOM errors or failed database writes. -The safe upper bound depends on Liveboard complexity. -Liveboards with an average of approximately 30 visualizations each provide a reasonable sizing baseline. - -* For `PARTIAL` and `PARTIAL_OBJECT`, there is no per-task object limit enforced by the API. -These policies write objects incrementally and are appropriate for large migration workloads. - -* The API payload size limit is 500 MB per request (infrastructure limit). -Contact ThoughtSpot Support if your use case requires a larger limit. - - -==== Avoid parallel imports of the same object - -Never submit tasks that include the same object in more than one active task simultaneously. -Concurrent writes to the same object cause a version conflict, and one of the tasks will fail. - -Design your import pipeline so that each object appears in at most one active import task at a time. -Sequence tasks, do not parallelize them across the same objects. - -==== Monitor the task queue and status - -The async import queue supports a maximum of 100 concurrent tasks. -Submitting more than 100 tasks at once causes the excess tasks to be rejected with a `FAILED` status immediately. - -Poll the `POST /api/rest/2.0/metadata/tml/async/status` endpoint to check task status. - -[width="100%", cols="1,4"] -[options='header'] -|==== -|Status value|Description - -|`IN_QUEUE` -|The task is waiting to be processed. -The queue limit is 100 concurrent tasks. -Tasks submitted beyond the limit are rejected immediately with status `FAILED`. - -|`IN_PROGRESS` -|The task is being processed. - -|`COMPLETED` -|The task processing is complete. -`COMPLETED` does not mean every object imported successfully. -Individual objects within the task have their own statuses. -Inspect per-object status in the response to identify failures. - -|`FAILED` -|The task failed. -This could be due to multiple reasons such as - the queue was full at submission time, a policy-level failure occurred, or an unrecoverable error was encountered during processing. -|==== - -*Recommended polling intervals:* - -The status API enforces a rate limit of 100 requests per minute. -Exceeding this limit returns an error. - -For practical use: - -* For small tasks, poll no more frequently than every 30 seconds. -* For large tasks, a polling interval of 1 minute is recommended, as larger tasks take proportionally longer to complete. - -==== Use API parameters correctly - -The following parameters in `POST /api/rest/2.0/metadata/tml/async/import` require careful use: - -`create_new`:: -Set `create_new: true` only when you want to create objects with new GUIDs, not update existing objects. -Setting this parameter on objects that already exist creates duplicates. -Do not set this parameter unless you are certain that new objects should be created. - -`skip_diff_check`:: -Set `skip_diff_check: true` only when you want to force a re-import of a TML file that has not changed since the previous import. -By default, ThoughtSpot identifies unchanged objects and skips them to reduce import time. -Enable this parameter only when unchanged files must be explicitly reprocessed. - -`enable_large_metadata_validation`:: -Set to `true` if the database contains multiple thousands of tables. -When enabled, ThoughtSpot validates schema one table at a time, which helps circumvent metadata fetching limitations of the Cloud Data Warehouse (CDW). -Default: `false`. - -`enable_personalized_view_upsert`:: -Set to `true` to enable update and insert of personalized views in a Liveboard during TML import. -When enabled, personalized views are preserved or created as part of the import operation instead of being discarded. -Default: `false`. - - -==== Schedule large imports during off-peak hours - -Large TML migrations can temporarily increase system resource usage. -Schedule bulk async imports during off-peak hours to reduce the risk of impacting users who are actively using the cluster. - - -=== Schedule import tasks - -You can import TML objects asynchronously by scheduling TML import tasks via `POST` request to POST `/api/rest/2.0/metadata/tml/async/import` API endpoint. You can send the following parameters in the API request body: - -[width="100%" cols="2,4,1"] -[options='header'] -|==== -|Form parameter|Description| Default -|`metadata_tmls` |__Array of strings__. Array of the TML strings. |__None__ -|`create_new` + -__Optional__ |__Boolean__. To create TML objects with new GUIDs during import, specify `true`. By default, ThoughtSpot updates the existing objects that have the same GUID as the objects you are importing. | `false` -|`all_orgs_context` + -__Optional__ |__Boolean__. Specify if import operation must be run for all Orgs on your instance. - -__Requires Org administration privileges to access TML objects across all Orgs.__| `false` - -|`import_policy` a|__String__. Policy to follow during import. The allowed values are: - -* `PARTIAL` -//Imports objects that validate successfully. Skips the objects that do not validate successfully and their dependent objects if any. -* `ALL_OR_NONE` -//Imports all objects that validate successfully. If the import fails for one object, no objects will be imported. -* `VALIDATE_ONLY` -//Validates the objects but does not import them. -* `PARTIAL_OBJECT` -//Imports objects that validate successfully and skips the objects that do not validate successfully. If the import fails for a visualization object in a Liveboard TML, the Liveboard will be imported without that visualization object. Similarly, if importing a relationship in a logical table fails, the table TML will be imported with warnings in the API response. -| `PARTIAL_OBJECT` - -|`skip_diff_check` + -__Optional__ -|__Boolean__ |`false` -|`enable_large_metadata_validation` + -__Optional__ - |__Boolean__ -|`false` -|`enable_personalized_view_upsert` + -__Optional__ -|__Boolean__ -|`false` -|==== -//// - - -|`skip_cdw_validation_for_tables` + -__Optional__ |__Boolean__. Skips Cloud Data Warehouse validation for table TML imports. | `false` -//// -==== Example request - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-host}/api/rest/2.0/metadata/tml/async/import' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "metadata_tmls": [ - "{\\\"guid\\\": \\\"2ed8192a-1e9d-47d1-810d-52b14cb0e9fe\\\",\\\"liveboard\\\": {\\\"name\\\": \\\"Total Sales\\\",\\\"visualizations\\\": [{\\\"id\\\": \\\"Viz_1\\\",\\\"answer\\\": {\\\"name\\\": \\\"Total quantity purchased, Total sales by region\\\",\\\"description\\\": \\\"test\\\",\\\"tables\\\": [{\\\"id\\\": \\\"(Sample) Retail - Apparel\\\",\\\"name\\\": \\\"(Sample) Retail - Apparel\\\"}],\\\"search_query\\\": \\\"[region] [quantity purchased] [sales]\\\",\\\"answer_columns\\\": [{\\\"name\\\": \\\"Total quantity purchased\\\"},{\\\"name\\\": \\\"Total sales\\\"},{\\\"name\\\": \\\"region\\\"}],\\\"table\\\": {\\\"table_columns\\\": [{\\\"column_id\\\": \\\"Total quantity purchased\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"Total sales\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"region\\\",\\\"show_headline\\\": false}],\\\"ordered_column_ids\\\": [\\\"region\\\",\\\"Total quantity purchased\\\",\\\"Total sales\\\"],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"tableVizPropVersion\\\\\\\": \\\\\\\"V1\\\\\\\"}\\\"},\\\"chart\\\": {\\\"type\\\": \\\"COLUMN\\\",\\\"chart_columns\\\": [{\\\"column_id\\\": \\\"Total quantity purchased\\\"},{\\\"column_id\\\": \\\"Total sales\\\"},{\\\"column_id\\\": \\\"region\\\"}],\\\"axis_configs\\\": [{\\\"x\\\": [\\\"region\\\"],\\\"y\\\": [\\\"Total quantity purchased\\\",\\\"Total sales\\\"]}],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"version\\\\\\\": \\\\\\\"V4DOT2\\\\\\\",\\\\\\\"chartProperties\\\\\\\": {\\\\\\\"responsiveLayoutPreference\\\\\\\": \\\\\\\"AUTO_ON\\\\\\\",\\\\\\\"chartSpecific\\\\\\\": {}},\\\\\\\"axisProperties\\\\\\\": [{\\\\\\\"id\\\\\\\": \\\\\\\"f6701821-5630-49cd-b26f-f98bebb4e98e\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"Y\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Total quantity purchased\\\\\\\"],\\\\\\\"isOpposite\\\\\\\": false}},{\\\\\\\"id\\\\\\\": \\\\\\\"1e086aef-236d-4cf0-8909-9e04e04a1ac4\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"Y\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Total sales\\\\\\\"],\\\\\\\"isOpposite\\\\\\\": true}},{\\\\\\\"id\\\\\\\": \\\\\\\"7be648d3-c791-43e4-bb13-63fea808f326\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"X\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"region\\\\\\\"]}}],\\\\\\\"systemSeriesColors\\\\\\\": [{\\\\\\\"serieName\\\\\\\": \\\\\\\"Total quantity purchased\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#48D1E0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"Total sales\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2E75F0\\\\\\\"}]}\\\"},\\\"display_mode\\\": \\\"CHART_MODE\\\"},\\\"viz_guid\\\": \\\"b8b38851-5980-40a1-bd88-608b7a9c6e86\\\"},{\\\"id\\\": \\\"Viz_2\\\",\\\"answer\\\": {\\\"name\\\": \\\"Total sales in a year\\\",\\\"tables\\\": [{\\\"id\\\": \\\"(Sample) Retail - Apparel\\\",\\\"name\\\": \\\"(Sample) Retail - Apparel\\\"}],\\\"search_query\\\": \\\"[sales] [store] [date].monthly [date].'\''this year'\''\\\",\\\"answer_columns\\\": [{\\\"name\\\": \\\"Month(date)\\\"},{\\\"name\\\": \\\"Total sales\\\"},{\\\"name\\\": \\\"store\\\"}],\\\"table\\\": {\\\"table_columns\\\": [{\\\"column_id\\\": \\\"Month(date)\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"Total sales\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"store\\\",\\\"show_headline\\\": false}],\\\"ordered_column_ids\\\": [\\\"store\\\",\\\"Month(date)\\\",\\\"Total sales\\\"],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"tableVizPropVersion\\\\\\\": \\\\\\\"V1\\\\\\\"}\\\"},\\\"chart\\\": {\\\"type\\\": \\\"LINE\\\",\\\"chart_columns\\\": [{\\\"column_id\\\": \\\"Month(date)\\\"},{\\\"column_id\\\": \\\"Total sales\\\"},{\\\"column_id\\\": \\\"store\\\"}],\\\"axis_configs\\\": [{\\\"x\\\": [\\\"Month(date)\\\"],\\\"y\\\": [\\\"Total sales\\\"],\\\"color\\\": [\\\"store\\\"]}],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"version\\\\\\\": \\\\\\\"V4DOT2\\\\\\\",\\\\\\\"chartProperties\\\\\\\": {\\\\\\\"responsiveLayoutPreference\\\\\\\": \\\\\\\"AUTO_ON\\\\\\\",\\\\\\\"chartSpecific\\\\\\\": {}},\\\\\\\"axisProperties\\\\\\\": [{\\\\\\\"id\\\\\\\": \\\\\\\"feb33c4a-614b-4623-9d12-1c4cf2250801\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"Y\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Total sales\\\\\\\"],\\\\\\\"isOpposite\\\\\\\": false}},{\\\\\\\"id\\\\\\\": \\\\\\\"e89293cb-d10a-40d5-b787-81be33cc8b81\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"X\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Month(date)\\\\\\\"]}}],\\\\\\\"systemSeriesColors\\\\\\\": [{\\\\\\\"serieName\\\\\\\": \\\\\\\"6a4acb32-9036-4d4c-a830-f2b06966a322\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#48D1E0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"39e5242e-43d0-4ef7-8673-73b12433e0c5\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2E75F0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"arizona (85226)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2E75F0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"arizona (86001)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#48D1E0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"california (91006)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FCC838\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"california (94702)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#06BF7F\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"colorado (80301)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#8C62F5\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"colorado (80920)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FF8142\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"connecticut (06110)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#ABC7F9\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"connecticut (06854)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#B5ECF2\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"delaware (19702)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FDE9AF\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"georgia (30022)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#9BE5CB\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"georgia (30329)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#D1C0FB\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"idaho (83704)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FFCCB3\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"illinois (60062)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2359B6\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"illinois (60642)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#369FAA\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"indiana (46250)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#BF982A\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"iowa (50266)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#049160\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"maryland (21045)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#6A4ABA\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"massachusetts (01701)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#C26232\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"massachusetts (02215)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#71A1F4\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"michigan (48103)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#82DFE9\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"michigan (49512)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FCD977\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"minnesota (55369)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#56D3A8\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"minnesota (55420)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#B094F8\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"missouri (63144)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FFA97E\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"montana (59106)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#163772\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"montana (59718)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#22636B\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"nevada (89052)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#785F1A\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"nevada (89145)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#025B3C\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"new hampshire (03860)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#422E75\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"new jersey (07936)\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#7A3D1F\\\\\\\"}]}\\\"},\\\"display_mode\\\": \\\"CHART_MODE\\\"},\\\"viz_guid\\\": \\\"7efc7b0e-e680-44a4-ba9c-3bd5d7272367\\\"},{\\\"id\\\": \\\"Viz_3\\\",\\\"answer\\\": {\\\"name\\\": \\\"Total sales by item type and region\\\",\\\"tables\\\": [{\\\"id\\\": \\\"(Sample) Retail - Apparel\\\",\\\"name\\\": \\\"(Sample) Retail - Apparel\\\"}],\\\"search_query\\\": \\\"[sales] [item type] [region]\\\",\\\"answer_columns\\\": [{\\\"name\\\": \\\"Total sales\\\"},{\\\"name\\\": \\\"item type\\\"},{\\\"name\\\": \\\"region\\\"}],\\\"table\\\": {\\\"table_columns\\\": [{\\\"column_id\\\": \\\"Total sales\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"item type\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"region\\\",\\\"show_headline\\\": false}],\\\"ordered_column_ids\\\": [\\\"item type\\\",\\\"region\\\",\\\"Total sales\\\"],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"tableVizPropVersion\\\\\\\": \\\\\\\"V1\\\\\\\"}\\\"},\\\"chart\\\": {\\\"type\\\": \\\"STACKED_COLUMN\\\",\\\"chart_columns\\\": [{\\\"column_id\\\": \\\"Total sales\\\"},{\\\"column_id\\\": \\\"item type\\\"},{\\\"column_id\\\": \\\"region\\\"}],\\\"axis_configs\\\": [{\\\"x\\\": [\\\"item type\\\"],\\\"y\\\": [\\\"Total sales\\\"],\\\"color\\\": [\\\"region\\\"]}],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"version\\\\\\\": \\\\\\\"V4DOT2\\\\\\\",\\\\\\\"chartProperties\\\\\\\": {\\\\\\\"responsiveLayoutPreference\\\\\\\": \\\\\\\"AUTO_ON\\\\\\\",\\\\\\\"chartSpecific\\\\\\\": {}},\\\\\\\"axisProperties\\\\\\\": [{\\\\\\\"id\\\\\\\": \\\\\\\"a330db6d-3714-4b5f-aed7-cca5ab679502\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"Y\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Total sales\\\\\\\"],\\\\\\\"isOpposite\\\\\\\": false}},{\\\\\\\"id\\\\\\\": \\\\\\\"96ac1ce3-7efd-455e-a569-2cd0792b5f95\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"X\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"item type\\\\\\\"]}}],\\\\\\\"systemSeriesColors\\\\\\\": [{\\\\\\\"serieName\\\\\\\": \\\\\\\"Total sales\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#48D1E0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"92153012-664c-458e-9a74-6138c5030838\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2E75F0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"east\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#06BF7F\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"midwest\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#FCC838\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"south\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#48D1E0\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"southwest\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#71A1F4\\\\\\\"},{\\\\\\\"serieName\\\\\\\": \\\\\\\"west\\\\\\\",\\\\\\\"color\\\\\\\": \\\\\\\"#2E75F0\\\\\\\"}]}\\\"},\\\"display_mode\\\": \\\"CHART_MODE\\\"},\\\"viz_guid\\\": \\\"9de47a0e-6f20-40ba-9a52-3374ee530f09\\\"},{\\\"id\\\": \\\"Viz_4\\\",\\\"answer\\\": {\\\"name\\\": \\\"Total sales by state\\\",\\\"tables\\\": [{\\\"id\\\": \\\"(Sample) Retail - Apparel\\\",\\\"name\\\": \\\"(Sample) Retail - Apparel\\\"}],\\\"search_query\\\": \\\"[state] [store] [sales]\\\",\\\"answer_columns\\\": [{\\\"name\\\": \\\"Total sales\\\"},{\\\"name\\\": \\\"state\\\"},{\\\"name\\\": \\\"store\\\"}],\\\"table\\\": {\\\"table_columns\\\": [{\\\"column_id\\\": \\\"Total sales\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"state\\\",\\\"show_headline\\\": false},{\\\"column_id\\\": \\\"store\\\",\\\"show_headline\\\": false}],\\\"ordered_column_ids\\\": [\\\"state\\\",\\\"store\\\",\\\"Total sales\\\"],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"tableVizPropVersion\\\\\\\": \\\\\\\"V1\\\\\\\"}\\\"},\\\"chart\\\": {\\\"type\\\": \\\"GEO_AREA\\\",\\\"chart_columns\\\": [{\\\"column_id\\\": \\\"Total sales\\\"},{\\\"column_id\\\": \\\"state\\\"},{\\\"column_id\\\": \\\"store\\\"}],\\\"axis_configs\\\": [{\\\"x\\\": [\\\"state\\\"],\\\"y\\\": [\\\"Total sales\\\"]}],\\\"client_state\\\": \\\"\\\",\\\"client_state_v2\\\": \\\"{\\\\\\\"version\\\\\\\": \\\\\\\"V4DOT2\\\\\\\",\\\\\\\"chartProperties\\\\\\\": {\\\\\\\"chartSpecific\\\\\\\": {}},\\\\\\\"axisProperties\\\\\\\": [{\\\\\\\"id\\\\\\\": \\\\\\\"e4943da4-f159-470c-836b-7c6c55d59c2f\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"Y\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"Total sales\\\\\\\"],\\\\\\\"isOpposite\\\\\\\": false}},{\\\\\\\"id\\\\\\\": \\\\\\\"b99d582a-b215-4381-89ad-280c451979e3\\\\\\\",\\\\\\\"properties\\\\\\\": {\\\\\\\"axisType\\\\\\\": \\\\\\\"X\\\\\\\",\\\\\\\"linkedColumns\\\\\\\": [\\\\\\\"state\\\\\\\"]}}],\\\\\\\"systemMultiColorSeriesColors\\\\\\\": [{\\\\\\\"serieName\\\\\\\": \\\\\\\"Total sales\\\\\\\",\\\\\\\"colorMap\\\\\\\": [{\\\\\\\"serieName\\\\\\\": \\\\\\\"state\\\\\\\",\\\\\\\"color\\\\\\\": [\\\\\\\"#ffffb2\\\\\\\",\\\\\\\"#fddd87\\\\\\\",\\\\\\\"#fba35d\\\\\\\",\\\\\\\"#f75534\\\\\\\",\\\\\\\"#f9140a\\\\\\\",\\\\\\\"#d70315\\\\\\\",\\\\\\\"#b10026\\\\\\\"]}]}]}\\\"},\\\"display_mode\\\": \\\"CHART_MODE\\\"},\\\"viz_guid\\\": \\\"4ab1ed61-2930-46d4-af6f-778279d7414a\\\"}],\\\"filters\\\": [{\\\"column\\\": [\\\"region\\\"],\\\"oper\\\": \\\"in\\\",\\\"values\\\": [\\\"Midwest\\\"],\\\"is_mandatory\\\": false,\\\"is_single_value\\\": false,\\\"display_name\\\": \\\"region\\\"}],\\\"layout\\\": {\\\"tabs\\\": [{\\\"name\\\": \\\"Tab 1\\\",\\\"description\\\": \\\"\\\",\\\"tiles\\\": [{\\\"visualization_id\\\": \\\"Viz_1\\\",\\\"x\\\": 0,\\\"y\\\": 0,\\\"height\\\": 8,\\\"width\\\": 6},{\\\"visualization_id\\\": \\\"Viz_4\\\",\\\"x\\\": 6,\\\"y\\\": 0,\\\"height\\\": 8,\\\"width\\\": 6}],\\\"id\\\": \\\"2c4014b5-a606-4639-8ad0-01032ff3fc13\\\"},{\\\"name\\\": \\\"Tab 2\\\",\\\"description\\\": \\\"\\\",\\\"tiles\\\": [{\\\"visualization_id\\\": \\\"Viz_2\\\",\\\"x\\\": 0,\\\"y\\\": 0,\\\"height\\\": 8,\\\"width\\\": 6},{\\\"visualization_id\\\": \\\"Viz_3\\\",\\\"x\\\": 6,\\\"y\\\": 0,\\\"height\\\": 8,\\\"width\\\": 6}],\\\"id\\\": \\\"185b4875-e7c5-43d2-a9bc-0a404107a3ec\\\"}]}}}\", \"info\": { \"filename\": \"Copy of Total Sales.liveboard.tml\", \"name\": \"Copy of Total Sales\", \"id\": \"2ed8192a-1e9d-47d1-810d-52b14cb0e9fe\", \"type\": \"liveboard\", \"status\": { \"status_code\": \"OK\" } }" - ], - "create_new": true, - "all_orgs_context": false, -}' ----- - -==== Example response - -If the API request is successful, ThoughtSpot schedules an import task, and returns the task name and ID in the API response: - -[source,JSON] ----- -{ - "tenant_id": "default-tenant-id", - "org_id": 0, - "task_id": "075c322f-b000-4776-9c44-89e13420980c", - "task_name": "ASYNC_TML_26:Nov:2024-06:06:24", - "import_response": null, - "task_status": "IN_QUEUE", - "author_id": "08c6b203-ff6e-4ed8-b923-35ebbbfef27b", - "import_policy": "PARTIAL_OBJECT", - "created_at": null, - "in_progress_at": null, - "completed_at": null, - "total_object_count": 2, - "object_processed_count": null, - "modified_at": null, - "author_display_name": "UserA" -} ----- - -===== Response codes - -[options="header", cols="1,4"] -|==== -|HTTP status code|Description -|**200**|Async TML Import Task submitted successfully -|**400**|Invalid request -|**401**|Unauthorized access -|**403**|Forbidden access -|**500**|Unexpected Error -|==== - -=== Fetch status of the TML import task - -To fetch the status of a scheduled import task, send a `POST` request to the `POST /api/rest/2.0/metadata/tml/async/status` API endpoint. - -In the request body, include the following attributes: - -[width="100%" cols="2,4,1"] -[options='header'] -|==== -|Form parameter|Description| Default -|`task_ids` |__Array of strings__. Task IDs assigned to the scheduled TML async import operations. | __None__ -| `task_status` | __Array of strings__. Status of the scheduled import tasks to filter on. The following options are available: + - -* `COMPLETED` + -* `IN_QUEUE` + -* `IN_PROGRESS` + -* `FAILED` -| __None__ -|`author_identifier` + -__Optional__ |__String__. GUID of the author who initiated the import request. | __None__ -|`include_import_response` + -__Optional__ |__Boolean__. Specify whether to include import response in the task status objects.| `false` -|`record_offset` + -__Optional__ |__Integer__. The offset point, starting from where the task status should -be included in the response. | `0` -|`record_size` + -__Optional__ a|__Integer__. The number of task statuses to include in the -response starting from offset position. - -[NOTE] -==== -The maximum limit for the `record_size` that user can pass in an API request is 50. If the `record_size` exceeds this threshold, the API returns a bad request error. To extend the `record_size` limit, contact ThoughtSpot Support. -==== -| `5` -|==== - -[IMPORTANT] -==== -You can poll up to 100 API requests per minute to get details of your TML import tasks. The API returns an error if you exceed this rate limit. -==== - -==== Example request - -[source,cURL] ----- -curl -X POST \ - --url 'https://{ThoughtSpot-host}/api/rest/2.0/metadata/tml/async/status' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - "record_offset": 0, - "record_size": 5, - "include_import_response": true, - "task_ids": [ - "c8c8c4da-0bc8-4460-8039-cfa7fd598335" - ], - "task_status": [ - "COMPLETED" - ], - "author_identifier": "95ac814f-eb01-4625-93c7-c7624b29d226" -}' ----- - -==== Example response - -If the API request is successful, ThoughtSpot returns the status details of the TML async import tasks. -If Orgs are enabled on your instance, the API returns task status only for objects within the current Org context. - -[source,JSON] ----- -{ - "status_list": [ - { - "tenant_id": "default-tenant-id", - "org_id": 0, - "task_id": "c8c8c4da-0bc8-4460-8039-cfa7fd598335", - "task_name": "ASYNC_TML_26:Nov:2024-06:06:24", - "import_response": { - "object": [ - { - "filename": "tml_0", - "zip_filename": "zip_tml_0", - "response": { - "status": { - "status_code": "ERROR", - "error_message": "Invalid YAML/JSON syntax in file." - } - }, - "request_index": 0 - }, - { - "filename": "tml_1", - "zip_filename": "zip_tml_1", - "response": { - "status": { - "status_code": "ERROR", - "error_message": "Invalid YAML/JSON syntax in file." - } - }, - "request_index": 1 - } - ], - "status": { - "status_code": "OK", - "error_code": 0, - "error_message": "" - } - }, - "task_status": "COMPLETED", - "author_id": "08c6b203-ff6e-4ed8-b923-35ebbbfef27b", - "import_policy": "PARTIAL_OBJECT", - "created_at": 1732601184212, - "in_progress_at": 1732601184255, - "completed_at": 1732601184476, - "total_object_count": 2, - "object_processed_count": 2, - "modified_at": 1732601184476, - "author_display_name": "UserA" - } - ], - "last_batch": true -} ----- - -===== Response codes - -[options="header", cols="1,4"] -|==== -|HTTP status code|Description -|**200**|Async TML import task status fetched successfully -|**400**|Invalid request -|**401**|Unauthorized access -|**403**|Forbidden access -|**500**|Unexpected Error -|==== - - -== Export a TML -To export the TML data, your account must have the `DATAMANAGEMENT` (Can manage data) or `ADMINISTRATION` (Can administer ThoughtSpot) privilege. - -The default format to export the objects is YAML is v1, and JSON in v2 APIs. To export the TML representation of the metadata objects from ThoughtSpot in JSON or YAML format, use one of the following endpoints: - -* link:https://developers.thoughtspot.com/docs/restV2-playground?apiResourceId=http%2Fapi-endpoints%2Fmetadata%2Fexport-metadata-tml[**POST** /api/rest/2.0/metadata/tml/export] (REST API v2) -* xref:tml-api.adoc#export[**POST** /tspublic/v1/metadata/tml/export] (REST API v1) - -To export the TML representation of the metadata objects in a *batch*, use one of the following endpoints: - -* link:https://developers.thoughtspot.com/docs/restV2-playground?apiResourceId=http%2Fapi-endpoints%2Fmetadata%2Fexport-metadata-tml-batched[**POST** /api/rest/2.0/metadata/tml/export/batch] (REST API v2) -* xref:tml-api.adoc#BatchExport[**POST** /tspublic/v1/metadata/tml/export/batch] (REST API v1) - -There are several export options available with these APIs: - -=== Metadata specification for Answers -To export a specific metadata object, specify the name or ID of the object. - -For Answer objects, the `identifier` is optional, and you can define parameters such as `session_identifier` and `generation_number` instead. These attributes can be used to export unsaved Answers generated from Spotter queries or Answers that do not have the name and ID assigned. - -=== Export associated objects - -To export associated objects, set the following attributes: - -* `export_associated` + -When set to `true`, exports the associated objects for the `export_ids` specified in the API request. The API exports any underlying Models, tables, or views for a given object. By default, the API does not export these underlying objects. -* `export_dependent` + -Specifies if the Tables of the referenced Connection object must be included in the export. -* `export_connection_as_dependent` + -Specifies if a Connection object must be included as a dependent object when exporting a Table, Model, Answer, or Liveboard TML. - -=== Export FQNs - -When `export_fqn=true`, the API exports the FQNs of the referenced objects in the TML data. For example, if you are exporting a Liveboard and its associated objects, the API returns the Liveboard TML data with the FQNs of the referenced Model. -Note that the FQN of a referenced object is the same as the GUID of that object. - -ThoughtSpot recommends adding the fqn property before importing the TML objects into the system, because only the name of a referenced object is not sufficient to identify the referenced object during TML import. For example, if your ThoughtSpot instance has two Models with the same name, the TML import for a Liveboard that uses one of these Models would fail unless the Liveboard TML includes the FQN of the referenced object. -The `export_fqn` attribute is useful when ThoughtSpot has multiple objects with the same name and you want to eliminate ambiguity during TML import. The `export_fqn=true` property adds the FQNs of the referenced objects in the TML export API response and saves the manual effort of adding FQNs for TML import. - -=== Export schema - -Specifies the schema version to use during TML export. For link:https://docs.thoughtspot.com/cloud/latest/models[Models, window=_blank], set `export_schema_version` to v2. -The v1 schema is used for Worksheet objects (Deprecated). - -=== Additional export options for REST API v2 -Following are some additional attributes which can be set for exporting objects: - -* `include_obj_id_ref` + -When set to `true`, exports the object ID of the referenced object. This flag will work only when the object ID feature is enabled. Contact ThoughtSpot Support to enable the feature. - -* `include_guid` + -When set to `true`, exports the guid of the object. This flag will work only when the object ID feature is enabled. Contact ThoughtSpot Support to enable the feature. -* `include_obj_id` + -When set to `true`, exports the object ID of the object. This flag will work only when the object ID feature is enabled. Contact ThoughtSpot Support to enable the feature. -* `export_with_associated_feedbacks` + -When set to `true`, exports the TML of an object along with all feedback, such as Spotter or Sage feedback, associated with that object. No feedback file will be exported if there are no feedback entries associated with the object -* `export_column_security_rules` [beta betaBackground]^Beta^ + -When set to `true`, exports the column-level security rules defined on the object. Contact ThoughtSpot Support to enable the feature. -* `export_with_column_aliases` [beta betaBackground]^Beta^ + -When set to `true`, export column aliases of the Model if the data Model includes any link:https://docs.thoughtspot.com/cloud/latest/column-aliases[column aliases, window=_blank]. - -=== Export in a batch -This API operation supports exporting User, User Group, and Role objects only. -To export objects in a batch, set the following additional attributes: - -* `batch_size` + -Exports the specified number of objects in a single API request. A batch size of up to 200 objects is allowed for a single API operation. - -* `batch_offset` + -Offsets the API response by the specified number. Batch offset value defines the starting position of the records for the results returned by the API. - -For more information, see the API documentation in REST API v2 Playground and xref:tml-api.adoc[Export a TML object using REST API v1]. - +* xref:tml-import.adoc[Import TML] +* xref:tml-export.adoc[Export TML] == TML modification -ThoughtSpot offers a lot of flexibility within its set of xref:intro-thoughtspot-objects.adoc[data objects], and there is no particular hierarchy to TML files, but rather just some rules. Visit this page for detailed information on xref:modify-tml.adoc[TML modification]. +Visit this page for detailed information on xref:modify-tml.adoc[TML modification]. == Limitations of working with TML files There are certain limitations to the changes you can apply by editing a ThoughtSpot object through TML. Visit link:https://docs.thoughtspot.com/cloud/latest/tml#_limitations_of_working_with_tml_files[Limitations of working with TML files, window=_blank] for detailed information. + [#yamlReimport] === YAML reimport in REST API v2 Playground If you are using the REST API Playground to import TML in YAML format, note that copying YAML content directly in the input field will likely result in the `Invalid YAML/JSON syntax in file` error. @@ -688,5 +135,4 @@ ThoughtSpot instances act as a constantly running service, so deployment only in But this changed with the link:https://developers.thoughtspot.com/docs/git-integration[Git integration] feature. ThoughtSpot now allows you to connect your deployment instance to a Git repository, push TML files to CI/CD pipelines, and deploy commits from your Git repository to your production environment. However, ThoughtSpot’s Git integration does not support moving objects within the same Org or application instance. For example, it does not support moving objects in an environment where xref:multitenancy-without-orgs[multi-tenancy is implemented using groups]. -/// - +//// diff --git a/modules/ROOT/pages/user-api.adoc b/modules/ROOT/pages/user-api.adoc index b2a284104..0d199750c 100644 --- a/modules/ROOT/pages/user-api.adoc +++ b/modules/ROOT/pages/user-api.adoc @@ -1,21 +1,24 @@ -= User API += REST API v1 - User API endpoints :toc: true :toclevels: 1 :page-title: User APIs -:page-pageid: user-api +:page-pageid: user-api-v1 :page-description: To create, update, and manage ThoughtSpot users programmatically, use the user API endpoints -The User APIs allow you to programmatically create, update, and administer ThoughtSpot users. + +include::{path}/rest-apiv1-deprecation-note.adoc[] == Supported operations +The User APIs allow you to programmatically create, update, and administer ThoughtSpot users. + include::{path}/user-api-list.adoc[] === Required permissions -You must have administrator access to create, edit, and delete a user, assign users to groups, transfer objects from one user to another, and invalidate, deactivate or activate a user session. +You must have administrator access to create, edit, and delete a user, assign users to groups, transfer objects from one user to another, and invalidate, deactivate, or activate a user session. -If you have a multi-tenant instance with Orgs feature enabled, the cluster admin can create a user and associate the user to an `orgid`. For more information about Orgs, see xref:orgs.adoc[Multi-tenancy with Orgs]. +If you have a multi-tenant instance with Orgs, the cluster administrator can create a user and associate the user to an `orgid`. For more information about Orgs, see xref:orgs.adoc[Multi-tenancy with Orgs]. [#create-user] == Create a user diff --git a/modules/ROOT/pages/webhooks-gcs-storage.adoc b/modules/ROOT/pages/webhooks-gcs-storage.adoc index 82482f85a..02da63c95 100644 --- a/modules/ROOT/pages/webhooks-gcs-storage.adoc +++ b/modules/ROOT/pages/webhooks-gcs-storage.adoc @@ -198,7 +198,7 @@ To create a webhook with GCS as the target destination for payload delivery: image::./images/webhook-create-gcp.png[Webhooks for GCS storage] -- //. Select xref:webhooks-ux.adoc#_creating_a_webhook[the authentication method] to authorize payloads to the destination endpoint. + -. To configure xref:webhooks-ux.adoc#_creating_a_webhook_connection[advanced settings] such as signature verification, custom headers, and URL query parameters, click **Advanced settings** and configure the fields as required. +. To configure advanced settings such as signature verification, custom headers, and URL query parameters, click **Advanced settings** and configure the fields as required. . Click *Save*. + If the webhook is created successfully, it is added to the Webhooks list and enabled by default. diff --git a/modules/ROOT/pages/webhooks-ux.adoc b/modules/ROOT/pages/webhooks-ux.adoc index a29518606..306bba6f4 100644 --- a/modules/ROOT/pages/webhooks-ux.adoc +++ b/modules/ROOT/pages/webhooks-ux.adoc @@ -63,7 +63,7 @@ You can create a webhook for the Liveboard schedule event type to send a lightwe For more information, see the following documentation: -* xref:webhooks-lb-schedule.adoc#_through_the_webhooks_page_in_ui[Webhook configuration for Liveboard scheduled events]. +* xref:webhooks-lb-schedule.adoc#_through_the_webhooks_page_in_ui[Webhook configuration for Liveboard scheduled events] * xref:webhooks-s3-storage.adoc[AWS S3 storage configuration for webhooks] * xref:webhooks-gcs-storage.adoc[GCS storage configuration for webhooks] diff --git a/modules/ROOT/pages/whats-new-prev-history.adoc b/modules/ROOT/pages/whats-new-prev-history.adoc index 1e4f18e0a..0de0de67b 100644 --- a/modules/ROOT/pages/whats-new-prev-history.adoc +++ b/modules/ROOT/pages/whats-new-prev-history.adoc @@ -1018,7 +1018,7 @@ You can now embed ThoughtSpot Search with Natural Language Search capabilities u Using `SageEmbed`, you can embed the ThoughtSpot Search interface with Natural Language Search components in your app and also customize the search experience as per your requirements. -For more information, see xref:embed-nls.adoc[Embed Natural Language Search]. +//For more information, see xref:embed-nls.adoc[Embed Natural Language Search]. ==== .Embed Playground enhancements @@ -1184,7 +1184,7 @@ For more information, see xref:version_control.adoc[Git integration and version ==== The Visual Embed SDK provides a new JavaScript library to embed the Search page with AI-powered features such as natural language search and AI-suggested answers. To view the AI-suggested answers, make sure the AI search support is enabled on the data source or worksheet used for searching data. -For more information, see xref:SageEmbed.adoc[SageEmbed SDK reference]. +//For more information, see xref:SageEmbed.adoc[SageEmbed SDK reference]. ==== .Visual Embed SDK diff --git a/modules/ROOT/pages/whats-new.adoc b/modules/ROOT/pages/whats-new.adoc index 55ec0e2c5..d9fc73c1f 100644 --- a/modules/ROOT/pages/whats-new.adoc +++ b/modules/ROOT/pages/whats-new.adoc @@ -22,6 +22,108 @@ This page lists new features, enhancements, and deprecated functionality introdu // *Status:* Current / Supported / Deprecated // *Affects:* Developers, Administrators, End Users // ============================================================ +== September 2026 + +**Release version**: ThoughtSpot Cloud 26.9.0.cl + +*Upgrade notes*: No breaking changes in this release. + +*Recommended SDK versions*: Visual Embed SDK v1.52.0 or later + +[.cl-table, cols="2,4", frame=none, grid=none] +|=== +a| +[.cl-label] +*Version 26.9.0.cl* + +a| + +[discrete] +==== Full application embed + +Default page settings:: +You can now embed Collections list page and set it as the default landing page using `Page.Collections` enumeration value. For more information, see xref:set-default-page.adoc#_set_the_default_page_using_pageid[Customizing default page]. + +Navigation panel customization:: +Embed developers can include *Collections* as a navigation option in the left navigation panel in full application embeds. For more information, see xref:full-app-customize.adoc[Customize the embedded ThoughtSpot experience]. + +--- + +[discrete] +==== Spotter embed + +Spotter visual experience enhancements:: +The Spotter interface is redesigned and enhanced to provide a more streamlined and conversational experience to embedding application users. The classic Spotter interface remains the default for existing deployments, and you can choose to enable the new experience using the `updatedSpotterExperience` parameter in the SDK. For more information, see xref:customize-spotter-embed.adoc#_spotter_interface_in_the_embedded_view[Spotter experience]. + +Spotter conversation sharing in embedded views:: +Users can now share saved Spotter conversations with other users and groups directly from the embedded Spotter interface or via REST APIs. For more information, see xref:customize-spotter-sharing.adoc[Customize Spotter conversation sharing] and xref:spotter-agent-sharing-apis.adoc[Sharing Spotter conversations]. + +--- + + +[discrete] +==== Browser history management in embedded application +When ThoughtSpot is embedded in a host application, internal navigation pushes new entries onto the browser history stack, causing the browser *Back* button to step through ThoughtSpot's internal pages before returning to the host application. To override the browser history behavior for embedding application users and prevent users from getting trapped in back-button loops inside the embedded iframe environment, set `overrideHistoryState` in the Visual Embed SDK. + +--- + + +[discrete] +==== Lazy loading enabled by default for full-height embeds +To improve the initial load performance of large Liveboards, lazy loading is now enabled by default when `fullHeight` is set to `true`. For more information, see xref:lazy-loading-fullheight.adoc[Lazy loading of Liveboard visualizations]. + +--- + +[discrete] +==== Custom app scheme allowlisting for mobile embeds +ThoughtSpot now supports adding custom app schemes such as `capacitor://localhost` and `ionic://localhost` to the CSP and CORS allowlist. This allows mobile applications built with hybrid frameworks such as Capacitor and Ionic to embed ThoughtSpot content. For more information, see xref:security-settings.adoc#custom-app-schemes[Security settings]. + +--- + +[discrete] +==== Upcoming changes to `EmbedEvent.Error` framework +In the upcoming ThoughtSpot Cloud 26.10.0.cl and Visual Embed SDK 1.53.0 versions, `EmbedEvent.Error` will include a `severity` field that categorizes errors into three levels, `SEV1`, `SEV2`, and `SEV3`. ThoughtSpot recommends reviewing your error handling logic to prepare for this change. For more information, see xref:embed-event-error-best-practices.adoc[Handling embed errors]. + +--- + + +[discrete] +==== Personalized Views TML portability + +The Personalized Views TML portability feature is now GA and enabled on all ThoughtSpot Embedded instances. For more information, see xref:tml-import.adoc#personalized-views-portability[Personalized Views portability]. + +--- + + +[discrete] +==== Visual Embed SDK +For information about the new features and enhancements introduced in Visual Embed SDK version 1.52.0, see xref:api-changelog.adoc[Visual Embed SDK changelog]. + +--- + + +[discrete] +==== REST API v2 +This release introduces new API endpoints for sharing Spotter conversations, managing Snowflake Semantic integrations, and other enhancements. +For more information, see the xref:rest-apiv2-changelog.adoc[REST API v2.0 changelog]. + +--- + +//// +[discrete] +==== Answer Export API + +The following enhancements in the `POST /api/rest/2.0/report/answer` endpoint are now GA. + +* *Pinned Answer export* from a Liveboard, using the new `type` parameter. +* *Personalized View* support to export data from a specific Personalized View of a Liveboard. +* *Spotter Answer export* in `XLSX` and `PDF`, in addition to `CSV` and `PNG`. +* *Custom PNG output*, using `x_resolution`, `y_resolution`, and `scaling`. + +For more information, see xref:report-apis-v2.adoc#_answer_report_api[Answer Report API]. + +--- +//// + +|=== == August 2026 @@ -40,10 +142,10 @@ a| ==== Spotter embedding Spotter Analysts [earlyAccess eaBackground]#Early Access#:: -Spotter now includes an *Analysts* panel in the sidebar that surfaces dedicated Spotter Analyst agents. Each Analyst is scoped to a specific data model and skill set, enabling your embedded users to start focused AI-driven conversations without manually selecting a data source. For more information, see xref:customize-spotter-embed.adoc#_spotter_analysts[Customize Spotter embed]. +Spotter now includes an *Analysts* panel in the sidebar that surfaces dedicated Spotter Analyst agents. Each Analyst is scoped to a specific data model and skill set, enabling your embedded users to start focused AI-driven conversations without manually selecting a data source. For more information, see xref:customize-spotter-analysts.adoc#_spotter_analysts[Customize Spotter Analysts]. Spotter onboarding starter prompts:: -Embedded Spotter interface supports onboarding starter prompts to guide first-time users. When enabled, Spotter presents suggested questions based on the connected data model. For more information, see xref:customize-spotter-embed.adoc#_spotter_starter_prompts[Enable starter prompts in Spotter]. +Embedded Spotter interface supports onboarding starter prompts to guide first-time users. When enabled, Spotter presents suggested questions based on the connected data model. For more information, see xref:customize-spotter-chat-experience.adoc#_spotter_starter_prompts[Enable starter prompts in Spotter]. --- @@ -66,7 +168,7 @@ Enables interactive filter chips that allow users to add, update, or remove filt [discrete] ==== Navigation and homepage V1/V2 deprecated [.version-badge.deprecated]#Deprecated# -Starting from ThoughtSpot Cloud 26.8.0.cl, the classic V1 and V2 navigation and homepage experience modes are deprecated. All ThoughtSpot Embedded sessions now render in the V3 navigation experience by default. For more information, see xref:full-app-customize.adoc#nav-v1-v2-deprecation[V1 and V2 deprecation]. +Starting from ThoughtSpot Cloud 26.8.0.cl, the classic V1 and V2 navigation and homepage experience modes are deprecated. All ThoughtSpot Embedded sessions now render in the V3 navigation experience by default. For more information, see xref:deprecated-features.adoc#v1-v2-exp-fullApp-embed[V1 and V2 deprecation]. --- @@ -74,7 +176,7 @@ Starting from ThoughtSpot Cloud 26.8.0.cl, the classic V1 and V2 navigation and ==== Wide logo dimension [.version-badge.breaking]#Breaking change# Starting from ThoughtSpot Cloud 26.8.0.cl, the recommended dimensions for the wide logo displayed on the ThoughtSpot login page have changed from 330x100px to *250x50px (5:1 aspect ratio)*. Logos uploaded at the previous dimensions may appear distorted or incorrectly scaled on the login screen. If you previously uploaded a wide logo at 330x100px, re-upload it at 250x50px to ensure correct display. -For more information, see xref:customize-style.adoc#wide-logo[Customize the login page logo]. +For more information, see xref:customize-style.adoc#logo-change[Customize the login page logo]. --- @@ -98,13 +200,13 @@ Two new fields have been added to the TML for Personalized Views: * A new `author` field is added to the Personalized View TML during export. This field is used to assign ownership during import. * Personalized Views now support `obj_id` for stable cross-environment object identity. -For more information, see xref:tml.adoc#personalized-views-portability[Personalized Views portability]. +For more information, see xref:tml-import.adoc#personalized-views-portability[Personalized Views portability]. --- [discrete] ==== Discoverability checkbox deprecation [.version-badge.breaking]#Breaking change# -The *Make this Liveboard Discoverable* checkbox has been removed from the ThoughtSpot UI. Embedding applications that relied on discoverability for content visibility should review their sharing logic and update user-facing guidance for content access. For more information, see xref:deprecated-features.adoc#liveboardAnswerDiscoverable[Deprecation announcements]. +The *Make this Liveboard Discoverable* checkbox has been removed from the ThoughtSpot UI. Embedding applications that relied on discoverability for content visibility should review their sharing logic and update user-facing guidance for content access. For more information, see xref:deprecated-features.adoc#liveboardDiscoverable[Deprecation announcements]. --- @@ -264,7 +366,7 @@ This release introduces the following enhancements for Spotter AI workflows and Spotter now includes data literacy skills that help users understand the underlying data model. Users can ask Spotter to explain available data sources, fields, and relationships in plain language within a conversation session. * Spotter AI APIs: + //** New REST API endpoints to configure and retrieve persistent behavioral xref:spotter-agent-instructions.adoc[instructions for the Spotter agent]. - New API endpoint xref:spotter-agent-apis.adoc#_stop_an_in_progress_agent_response[stop and cancel a long-running Spotter response]. + New API endpoint xref:spotter-agent-conversation-apis.adoc#_stop_an_in_progress_agent_response[stop and cancel a long-running Spotter response]. --- @@ -444,7 +546,7 @@ Current period inclusion in rolling date filters:: The rolling date filters with the **Last ** and **Next ** filter types support including current period. Developers can disable, show, or hide this option using `isThisPeriodInDateFiltersEnabled` or `Action.IncludeCurrentPeriod`. Liveboard PNG export:: -The PNG export workflow in the `/api/rest/2.0/report/liveboard` REST API is enhanced to provide high-resolution PNG files. The legacy PNG workflow is deprecated in 26.4.0.cl. For more information about breaking changes and deprecation guidelines, see xref:deprecated-features.adoc[Deprecation announcements]. For information about the new PNG download workflow, see xref:data-report-v2-api.adoc#_liveboard_report_api[Liveboard report API documentation]. +The PNG export workflow in the `/api/rest/2.0/report/liveboard` REST API is enhanced to provide high-resolution PNG files. The legacy PNG workflow is deprecated in 26.4.0.cl. For more information about breaking changes and deprecation guidelines, see xref:deprecated-features.adoc[Deprecation announcements]. For information about the new PNG download workflow, see xref:report-apis-v2.adoc#_liveboard_report_api[Liveboard report API documentation]. --- diff --git a/modules/tutorials/pages/spotter/spotter-in-custom-chatbot.adoc b/modules/tutorials/pages/spotter/spotter-in-custom-chatbot.adoc index 6156b7802..ba735c836 100644 --- a/modules/tutorials/pages/spotter/spotter-in-custom-chatbot.adoc +++ b/modules/tutorials/pages/spotter/spotter-in-custom-chatbot.adoc @@ -86,9 +86,7 @@ div.append(container); app.insertAdjacentElement("beforeend", div); ---- -== That's all! - -And that’s a wrap! This was a super quick tutorial on how to use Spotter embed APIs to integrate conversational analytics with your chatbot! +== Next steps Visit the link:https://codesandbox.io/p/sandbox/bodyless-sample-doc-5q3dwr[CodeSandbox^] to see it in action in a sample chatbot we created. Here is the complete code used in this tutorial: diff --git a/src/assets/styles/admonition.scss b/src/assets/styles/admonition.scss index e7dd3e6f4..2d06fa93d 100644 --- a/src/assets/styles/admonition.scss +++ b/src/assets/styles/admonition.scss @@ -4,6 +4,17 @@ margin: 1.4rem 0 0; line-height: $admonition-content-line-height; + // Admonitions render their icon+content layout as a plain, class-less + // (Asciidoctor's own template — not a real [cols=...] table + // block), but Document/index.scss's generic `table` rule still matches + // it and adds a flat grey border-top that clashes with td.content's + // rounded corner below it. Reset it here rather than touching the + // shared rule, since real content tables (with the .tableblock class) + // should keep that border. + & > table { + border-top: none; + } + p { font-size: 13px; } @@ -80,5 +91,24 @@ table-layout: fixed; position: relative; width: 100%; + + // Asciidoctor renders this as a plain, class-less
(its own + // icon+content layout template, not a real [cols=...] table block), + // but Document/index.scss's generic `table` rule still matches it + // and adds a flat grey border-top with no radius — it extends past + // td.content's rounded top-right corner below it. Reset it here + // rather than touching the shared rule, since real content tables + // (with the .tableblock class) should keep that border. + border-top: none; } +} + +// Inline `code` normally sits on the near-white --code-text-bg, which in +// light mode reads as a stark, disconnected chip against a tinted +// admonition background (e.g. the note block's light blue). Blend it into +// the ambient tint with a translucent overlay instead of a fixed color. +#wrapper[data-theme='light'] .documentWrapper .admonitionblock code, +#docsModal[data-theme='light'] .documentWrapper .admonitionblock code { + background: rgba(0, 0, 0, 0.06); + border-color: rgba(0, 0, 0, 0.12); } \ No newline at end of file diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss index e64430bde..949e14305 100644 --- a/src/assets/styles/index.scss +++ b/src/assets/styles/index.scss @@ -633,7 +633,7 @@ button { } .tableContainer { - border: 0.5px solid $disabledcolor; + border: 0.5px solid var(--border-color); padding: 0 0 0 5px; overflow-x: auto; } @@ -655,9 +655,10 @@ button { .admonitionblock.note { border-left: 4px solid var(--var-note-color); td.content { - border: 1px solid var(--note-border-color); + border: 0.5px solid var(--note-border-color); + border-left: none; box-shadow: var(--box-shadow); - border-radius: 5px !important;; + border-radius: 0 5px 5px 0 !important; background: var(--note-block-color); } @@ -680,8 +681,9 @@ button { border-left: 4px solid var(--var-important-color); td.content { border: 1px solid var(--important-border-color); + border-left: none; box-shadow: var(--box-shadow); - border-radius: 5px !important; + border-radius: 0 5px 5px 0 !important; background: var(--important-block-color); } td.icon { @@ -694,8 +696,9 @@ button { border-left: 5px solid $warning-color; td.content { border: 1px solid $warning-color; + border-left: none; box-shadow: var(--box-shadow); - border-radius: 5px !important; + border-radius: 0 5px 5px 0 !important; } td.icon { left: 20px !important; @@ -707,8 +710,9 @@ button { border-left: 5px solid $caution-color; td.content { border: 1px solid $caution-color; + border-left: none; box-shadow: var(--box-shadow); - border-radius: 5px !important; + border-radius: 0 5px 5px 0 !important; } td.icon { left: 20px !important; @@ -1278,17 +1282,7 @@ a.anchor { } } -// Walkthroughs landing page — one wrapper around the hero text AND the card -// grid, with the gradient wash as a position:absolute layer sized to that -// whole wrapper instead of its own fixed-height box. A boxed hero (even a -// generously tall one) still has a hard bottom edge where overflow:hidden -// clips the blur/falloff mid-fade — visible as a seam or, with a taller box, -// a softer rounded silhouette. Sizing the layer to the full page instead -// means the blobs have all the room they need to fade out completely on -// their own before any edge is reached, so nothing is left to clip. -// It also means the gradient no longer reserves its own vertical space, so -// the hero text and the card grid below sit at normal content spacing -// instead of being pushed apart by an artificial min-height. +// Walkthroughs landing page .walkthroughs-page { position: relative; padding-top: 48px; @@ -1300,12 +1294,6 @@ a.anchor { .radiance-bg { position: absolute; - // Bleeds under this page's 60px/60px left-right content padding AND - // .doc-wrapper-detail's shared 20px top padding, so the wash - // reaches the header on all three edges instead of leaving a plain - // gap — matching the home page, which has no such padding to begin - // with. Bottom stays 0: the card grid below should keep its normal - // padding untouched. inset: -20px -60px 0 -60px; @media (max-width: $mobile-resolution-max) { @@ -1315,19 +1303,6 @@ a.anchor { inset: 0; } - // home's ::after mask (above) uses %-based stops, which are relative - // to its OWN box — since that box now spans the whole page, a % - // stop would stretch the fade-out proportionally with page length, - // tinting the cards. It also only masks down to its own 100% stop; - // giving it a shorter *height* instead (tried first) left the - // segment between that height and .radiance-bg's real (page-length) - // bottom completely unmasked, so the raw blobs showed through at - // full strength there with a hard cutoff at the very end — visible - // in a screenshot as full-strength color straight through the card - // row. Fixed px stops sidestep both: the fade still completes at a - // constant depth, and every pixel past 190px keeps resolving to the - // final (fully opaque, page-matching) stop, all the way to the - // page's actual bottom edge. &::after { background: linear-gradient( to bottom, @@ -1342,17 +1317,7 @@ a.anchor { } // pink/purple/blue are home's values (tuned for its taller banner — - // h1 + search bar — where their cores sit ~200px down). This page's - // hero is just a heading + one line of text, and the gap to the - // cards is intentionally kept tight, so the visible band above is - // only ~190px (the mask height above) — home's positions would put - // each blob's core below that band, in the now-flattened tail, so - // only their pale outer edges would show. Pulling all three up - // brings their cores (peak color) back inside the visible band — - // but that also means this page actually shows each blob's full- - // strength core, where home (by design) never does. Same alpha as - // home would read far more saturated here, so it's toned down to - // land at a similar visual intensity to home/the reference. + // h1 + search bar — where their cores sit ~200px down). .blob-pink { top: -31vh; background: radial-gradient(ellipse at center, rgba(255, 93, 142, 0.16) 0%, transparent 68%); @@ -1839,7 +1804,7 @@ a.anchor { /* optional .cl-label role on a paragraph in the left cell */ .cl-label p { display: inline-block; - border: 1px solid var(--rel-notes-pill-border); + border: 0.5px solid var(--rel-notes-pill-border); background-color: var(--rd-comp-color-button-primary-on-color-hover); color: var(--rel-notes-tag-text); font-size: 14px; diff --git a/src/assets/styles/variables.scss b/src/assets/styles/variables.scss index 7cab3f66f..b6c551c5a 100644 --- a/src/assets/styles/variables.scss +++ b/src/assets/styles/variables.scss @@ -183,11 +183,7 @@ $tag-color-light: $lightgrey; // --------------------------------------------------------------------------- // radiant remap a custom property whose value contains var() is resolved on -// the element where it is DECLARED, not where it is used. If we alias -// --body-background-color: var(--rd-sys-color-background-base); -// only on :root, dark mode would resolve against :root's (light) token and -// silently stop working. So the SAME alias block must be emitted on every -// element that carries data-theme. Hence one mixin, included twice. +// the element where it is DECLARED, not where it is used. // --------------------------------------------------------------------------- @mixin ts-docs-radiant-aliases { @@ -334,7 +330,7 @@ $tag-color-light: $lightgrey; --body-background-color: #1F2024; --table-header-bg: #26282C; --copy-page-menu-bg: #26282C; - --rel-notes-tag-bg-color: #A0C4FF; + --rel-notes-tag-bg-color: var(--note-block-color); --rel-notes-tag-text: #71a1f4; --rel-notes-pill-border: #278CFF; /* dark-mode-only admonition background — light mode keeps its existing diff --git a/src/components/Document/index.scss b/src/components/Document/index.scss index 39de82de8..bdc41340a 100644 --- a/src/components/Document/index.scss +++ b/src/components/Document/index.scss @@ -23,30 +23,36 @@ padding: 8px 14px; font-size: 13px; font-weight: 500; - color: #1d232f !important; - background: #fff; + color: var(--primary-color) !important; + background: var(--panel-bg-color); border-radius: 100px; text-decoration: none; white-space: nowrap; pointer-events: all; - box-shadow: - 0 4px 16px 0 rgba(25, 35, 49, 0.14), - 0 1px 4px 0 rgba(25, 35, 49, 0.06); + box-shadow: var(--box-shadow-hover); transition: box-shadow 0.15s ease; font-family: 'Optimo-Plain', sans-serif; border: 1px solid transparent; isolation: isolate; - // Sparkle icon + // Sparkle icon — shape supplied as a mask so its color follows + // --rd-sys-color-content-brand, the same token the FloatingAssistant + // widget's own sparkle icon (IconColor.BLUE) resolves its fill from, + // keeping the two in sync in both themes. &::before { content: ''; display: inline-block; width: 16px; height: 16px; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 27' fill='%232770EF' stroke='none'%3E%3Cpath fill='%232770EF' stroke='none' d='M8.25809 7.21109C8.83155 5.59342 11.1191 5.59349 11.6927 7.21109L13.4163 12.0753C13.4919 12.2885 13.6602 12.4568 13.8733 12.5324L18.7376 14.256C20.3555 14.8294 20.3555 17.1172 18.7376 17.6906L13.8733 19.4142C13.6601 19.4898 13.4918 19.658 13.4163 19.8712L11.6927 24.7355C11.1191 26.353 8.83157 26.3531 8.25809 24.7355L6.53445 19.8712C6.4589 19.658 6.29064 19.4898 6.07742 19.4142L1.21316 17.6906C-0.404397 17.1171 -0.404379 14.8295 1.21316 14.256L6.07742 12.5324C6.29058 12.4568 6.45883 12.2885 6.53445 12.0753L8.25809 7.21109ZM20.2805 0.49136C20.6395 -0.163697 21.6064 -0.163877 21.9651 0.49136L22.0315 0.642727L22.888 3.05972L25.3059 3.91616C26.1625 4.21966 26.1622 5.43079 25.3059 5.73452L22.888 6.59097L22.0315 9.00894C21.7279 9.86544 20.5167 9.86552 20.2132 9.00894L19.3567 6.59097L16.9397 5.73452C16.0831 5.43098 16.0831 4.21969 16.9397 3.91616L19.3567 3.05972L20.2132 0.642727L20.2805 0.49136Z'/%3E%3C/svg%3E"); - background-size: contain; - background-repeat: no-repeat; - background-position: center; + background-color: var(--rd-sys-color-content-brand, #2770EF); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 27'%3E%3Cpath d='M8.25809 7.21109C8.83155 5.59342 11.1191 5.59349 11.6927 7.21109L13.4163 12.0753C13.4919 12.2885 13.6602 12.4568 13.8733 12.5324L18.7376 14.256C20.3555 14.8294 20.3555 17.1172 18.7376 17.6906L13.8733 19.4142C13.6601 19.4898 13.4918 19.658 13.4163 19.8712L11.6927 24.7355C11.1191 26.353 8.83157 26.3531 8.25809 24.7355L6.53445 19.8712C6.4589 19.658 6.29064 19.4898 6.07742 19.4142L1.21316 17.6906C-0.404397 17.1171 -0.404379 14.8295 1.21316 14.256L6.07742 12.5324C6.29058 12.4568 6.45883 12.2885 6.53445 12.0753L8.25809 7.21109ZM20.2805 0.49136C20.6395 -0.163697 21.6064 -0.163877 21.9651 0.49136L22.0315 0.642727L22.888 3.05972L25.3059 3.91616C26.1625 4.21966 26.1622 5.43079 25.3059 5.73452L22.888 6.59097L22.0315 9.00894C21.7279 9.86544 20.5167 9.86552 20.2132 9.00894L19.3567 6.59097L16.9397 5.73452C16.0831 5.43098 16.0831 4.21969 16.9397 3.91616L19.3567 3.05972L20.2132 0.642727L20.2805 0.49136Z'/%3E%3C/svg%3E"); + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 27'%3E%3Cpath d='M8.25809 7.21109C8.83155 5.59342 11.1191 5.59349 11.6927 7.21109L13.4163 12.0753C13.4919 12.2885 13.6602 12.4568 13.8733 12.5324L18.7376 14.256C20.3555 14.8294 20.3555 17.1172 18.7376 17.6906L13.8733 19.4142C13.6601 19.4898 13.4918 19.658 13.4163 19.8712L11.6927 24.7355C11.1191 26.353 8.83157 26.3531 8.25809 24.7355L6.53445 19.8712C6.4589 19.658 6.29064 19.4898 6.07742 19.4142L1.21316 17.6906C-0.404397 17.1171 -0.404379 14.8295 1.21316 14.256L6.07742 12.5324C6.29058 12.4568 6.45883 12.2885 6.53445 12.0753L8.25809 7.21109ZM20.2805 0.49136C20.6395 -0.163697 21.6064 -0.163877 21.9651 0.49136L22.0315 0.642727L22.888 3.05972L25.3059 3.91616C26.1625 4.21966 26.1622 5.43079 25.3059 5.73452L22.888 6.59097L22.0315 9.00894C21.7279 9.86544 20.5167 9.86552 20.2132 9.00894L19.3567 6.59097L16.9397 5.73452C16.0831 5.43098 16.0831 4.21969 16.9397 3.91616L19.3567 3.05972L20.2132 0.642727L20.2805 0.49136Z'/%3E%3C/svg%3E"); + -webkit-mask-size: contain; + mask-size: contain; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; flex-shrink: 0; position: relative; z-index: 1; @@ -81,11 +87,9 @@ } &:hover { - color: #1d232f !important; + color: var(--primary-color) !important; text-decoration: none; - box-shadow: - 0 4px 16px 0 rgba(25, 35, 49, 0.14), - 0 1px 4px 0 rgba(25, 35, 49, 0.06); + box-shadow: var(--box-shadow-hover); &::after { opacity: 1; @@ -94,6 +98,11 @@ } } +#wrapper[data-theme='dark'] .selection-cta-button, +#docsModal[data-theme='dark'] .selection-cta-button { + background: #26282C; +} + .documentWrapper { width: calc(98%); color: var(--primary-color); @@ -246,9 +255,9 @@ display: inline-flex; align-items: center; padding: 4px 10px; - font-size: 13px; + font-size: 14px; font-weight: 500; - color: var(--nav-accent-color); + color: #71a1f4; background: transparent; border: none; border-radius: 5px; @@ -669,11 +678,7 @@ pre { } } -// Walkthroughs landing page only — zeroed out entirely (rather than mirrored -// like other pages) so .radiance-bg's own negative inset has a clean 0 -// baseline to bleed from on all three edges. Compound selector (higher -// specificity than .doc-wrapper-detail alone) so it doesn't need source -// order and doesn't affect any other page using .doc-wrapper-detail. +// Walkthroughs landing page only .doc-wrapper-detail.doc-walkthroughs { padding: 0; @media (max-width: $mobile-resolution-max) { diff --git a/src/components/Document/index.tsx b/src/components/Document/index.tsx index 5a2305447..21e93ad04 100644 --- a/src/components/Document/index.tsx +++ b/src/components/Document/index.tsx @@ -39,6 +39,13 @@ const Document = (props: { if (target.closest('.selection-cta-button')) return; if (target.closest('.floating-assistant__panel, .floating-assistant__chip-ring')) return; + // Only offer "Ask SpotterCode" for selections inside the main article + // body — not the left nav, header, footer, or right-side doc map/TOC. + if (!target.closest('.documentView')) { + setSelectionPos(null); + return; + } + // If mouse didn't move (plain click, not a drag-select), don't re-show const moved = Math.abs(e.clientX - mouseDownX) > 3 || Math.abs(e.clientY - mouseDownY) > 3; if (!moved) return; diff --git a/src/components/FloatingAssistant/index.scss b/src/components/FloatingAssistant/index.scss index f8276f276..29ef7857b 100644 --- a/src/components/FloatingAssistant/index.scss +++ b/src/components/FloatingAssistant/index.scss @@ -1,6 +1,88 @@ @import '../../assets/styles/variables.scss'; @import '../../assets/styles/highlight.scss'; +// ── Theme tokens ──────────────────────────────────────────────────────────── +#floating-assistant-root { + --fa-bg: #fff; + --fa-panel-bg: #fff; + --fa-surface: #F6F8FA; + --fa-surface-hover: #eef1f5; + --fa-border: #EAEDF2; + --fa-border-strong: #e3e6eb; + --fa-text: #1d232f; + --fa-text-secondary: #5f6368; + --fa-text-muted: #a5acb9; + --fa-accent: #2770ef; + --fa-accent-hover: #1a5fd4; + --fa-btn-primary-pressed: #1a5fd4; + --fa-btn-primary-icon-hover: #fff; + --fa-btn-primary-icon-pressed: #fff; + --fa-btn-secondary-bg: #fff; + --fa-btn-secondary-bg-hover: #F6F8FA; + --fa-btn-secondary-bg-pressed: #eef1f5; + --fa-user-bubble-bg: #f1f4f8; + --fa-user-bubble-border: #e8eaed; + --fa-scrollbar: #d0d4db; + --fa-scrollbar-hover: #a5acb9; + --fa-scroll-btn-bg: #fff; + --fa-scroll-btn-border: #e0e4ea; + --fa-shadow: 0 4px 16px 0 rgba(25, 35, 49, 0.10); + --fa-shadow-hover: 0 8px 24px 0 rgba(25, 35, 49, 0.16); + --fa-panel-shadow: -4px 0 24px 0 rgba(25, 35, 49, 0.10); + --fa-input-border-idle: #d0d4db; + --fa-input-row-border: rgba(0, 0, 0, 0.06); + --fa-input-row-bg: rgba(255, 255, 255, 0.6); + --fa-fade-color: #fff; + --fa-code-inline-bg: #f1f4f8; + --fa-code-inline-border: #e3e6eb; + --fa-hover-overlay: rgba(0, 0, 0, 0.06); + --fa-panel-wash-1: rgba(255, 120, 160, 0.3); + --fa-panel-wash-2: rgba(160, 100, 255, 0.2); + --fa-panel-wash-3: rgba(100, 160, 255, 0.3); +} + +#floating-assistant-root[data-theme='dark'] { + --fa-bg: #26282C; + --fa-panel-bg: #1F2024; + --fa-surface: #26282C; + --fa-surface-hover: #2f333b; + --fa-border: #34363C; + --fa-border-strong: #34363C; + --fa-text: #e6edf3; + --fa-text-secondary: #9098a8; + --fa-text-muted: #8b949e; + --fa-accent: #71a1f4; + --fa-accent-hover: #abc7f9; + --fa-btn-primary-pressed: #cedcf5; + --fa-btn-primary-icon-hover: #dee8fa; + --fa-btn-primary-icon-pressed: #cedcf5; + --fa-btn-secondary-bg: #2f3237; + --fa-btn-secondary-bg-hover: var(--rd-sys-color-background-secondary-hover); + --fa-btn-secondary-bg-pressed: #60656c; + --fa-user-bubble-bg: #26282C; + --fa-user-bubble-border: #34363C; + --fa-scrollbar: #3a3f4b; + --fa-scrollbar-hover: #545b6b; + --fa-scroll-btn-bg: #2a3142; + --fa-scroll-btn-border: #3a4255; + --fa-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.4); + --fa-shadow-hover: 0 8px 24px 0 rgba(0, 0, 0, 0.5); + --fa-panel-shadow: -4px 0 24px 0 rgba(0, 0, 0, 0.4); + --fa-input-border-idle: #3a3f4b; + --fa-input-row-border: rgba(255, 255, 255, 0.08); + --fa-input-row-bg: rgba(31, 32, 36, 0.6); + --fa-fade-color: #1F2024; + --fa-code-inline-bg: #2a3142; + --fa-code-inline-border: #3a4255; + --fa-hover-overlay: rgba(255, 255, 255, 0.08); + // Same wash hues at much lower opacity — on the dark panel background the + // light-mode opacities read as a saturated, concentrated band instead of + // the soft diffused glow the reference design uses. + --fa-panel-wash-1: rgba(255, 120, 160, 0.10); + --fa-panel-wash-2: rgba(160, 100, 255, 0.07); + --fa-panel-wash-3: rgba(100, 160, 255, 0.10); +} + // ── Chip trigger ───────────────────────────────────────────────────────────── .floating-assistant__chip { position: fixed; @@ -12,19 +94,19 @@ justify-content: center; width: 56px; height: 56px; - background: #fff; + background: var(--fa-bg); border: 2px solid transparent; border-radius: 50%; cursor: pointer; background-clip: padding-box; - box-shadow: 0 4px 16px 0 rgba(25, 35, 49, 0.10); + box-shadow: var(--fa-shadow); transition: box-shadow 0.2s ease, transform 0.2s ease; outline: 2px solid transparent; // Gradient border using outline + pseudo-element on a wrapper isn't needed — // use a parent wrapper div for the gradient ring &:hover { - box-shadow: 0 8px 24px 0 rgba(25, 35, 49, 0.16); + box-shadow: var(--fa-shadow-hover); } svg { @@ -32,7 +114,7 @@ height: 26px; position: relative; z-index: 1; - color: #2770ef; + color: var(--fa-accent); } } @@ -47,7 +129,7 @@ background: linear-gradient(135deg, #8C62F5, #48D1E0, #2770EF); padding: 1px; z-index: 1001; - box-shadow: 0 4px 16px 0 rgba(25, 35, 49, 0.10); + box-shadow: var(--fa-shadow); cursor: pointer; .floating-assistant__chip { @@ -83,18 +165,18 @@ bottom: 0; width: 360px; background: - linear-gradient(180deg, transparent 0%, #fff 35%), + linear-gradient(180deg, transparent 0%, var(--fa-panel-bg) 35%), linear-gradient(90deg, - rgba(255, 120, 160, 0.3) 0%, - rgba(160, 100, 255, 0.2) 60%, - rgba(100, 160, 255, 0.3) 90% + var(--fa-panel-wash-1) 0%, + var(--fa-panel-wash-2) 60%, + var(--fa-panel-wash-3) 90% ), - #fff; + var(--fa-panel-bg); display: flex; flex-direction: column; overflow: hidden; z-index: 1002; - box-shadow: -4px 0 24px 0 rgba(25, 35, 49, 0.10); + box-shadow: var(--fa-panel-shadow); animation: fa-slide-in 0.25s ease-out forwards; &.closing { @@ -102,7 +184,7 @@ } &--conversation { - background: #fff; + background: var(--fa-panel-bg); } &--embedded { @@ -121,7 +203,7 @@ background: transparent; border: none; outline: none; - border-bottom: 1px solid #EAEDF2; + border-bottom: 1px solid var(--fa-border); } .floating-assistant__close-btn { @@ -133,16 +215,17 @@ justify-content: center; padding: 4px; border-radius: 4px; + color: var(--fa-text); transition: background 0.15s; - &:hover { background: #f1f4f8; } + &:hover { background: var(--fa-surface); } } .floating-assistant__title { font-size: 16px; font-weight: 600; font-family: 'Optimo-Plain', sans-serif; - color: #1d232f; + color: var(--fa-text); } @@ -160,12 +243,12 @@ &::-webkit-scrollbar { width: 4px; } &::-webkit-scrollbar-track { background: transparent; } &::-webkit-scrollbar-thumb { - background: #d0d4db; + background: var(--fa-scrollbar); border-radius: 2px; - &:hover { background: #a5acb9; } + &:hover { background: var(--fa-scrollbar-hover); } } scrollbar-width: thin; - scrollbar-color: #d0d4db transparent; + scrollbar-color: var(--fa-scrollbar) transparent; } // ── Messages fade + scroll-to-bottom ───────────────────────────────────────── @@ -183,7 +266,7 @@ left: 0; right: 0; height: 48px; - background: linear-gradient(to top, #fff 0%, transparent 100%); + background: linear-gradient(to top, var(--fa-fade-color) 0%, transparent 100%); opacity: 0; transition: opacity 0.2s ease; } @@ -203,17 +286,13 @@ display: inline-flex; align-items: center; justify-content: center; - background: #fff; - border: 1px solid #e0e4ea; + background: var(--fa-scroll-btn-bg); + border: 1px solid var(--fa-scroll-btn-border); border-radius: 50%; width: 28px; height: 28px; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,0.1); - @media (prefers-color-scheme: dark) { - background: #2a3142; - border-color: #3a4255; - } } @keyframes fa-fade-in { @@ -255,12 +334,12 @@ font-size: 22px; font-weight: 700; font-family: 'Optimo-Plain', sans-serif; - color: #1d232f; + color: var(--fa-text); line-height: 1.3; letter-spacing: -0.4px; text-align: center; - span { color: #2770ef; } + span { color: var(--fa-accent); } } .floating-assistant__suggestions { @@ -272,10 +351,10 @@ } .floating-assistant__suggestion { - background: #F6F8FA; - border: 1px solid #EAEDF2; + background: var(--fa-surface); + border: 1px solid var(--fa-border); border-radius: 40px; - color: #1d232f; + color: var(--fa-text); cursor: pointer; font-size: 12px; font-family: 'Optimo-Plain', sans-serif; @@ -287,7 +366,7 @@ animation: fa-suggestion-in 0.3s ease-out both; opacity: 0; - &:hover { background: #eef1f5; } + &:hover { background: var(--fa-surface-hover); } } @keyframes fa-suggestion-in { @@ -320,7 +399,7 @@ .floating-assistant__timestamp { font-size: 11px; - color: #a5acb9; + color: var(--fa-text-muted); font-family: 'Optimo-Plain', sans-serif; } @@ -338,14 +417,14 @@ background: none; &:hover { - background: #d0d4db; + background: var(--fa-scrollbar); } &--send { - background: #2770ef; + background: var(--fa-accent); &:hover { - background: #1a5fd4; + background: var(--fa-accent-hover); } } } @@ -385,13 +464,13 @@ // User bubble — light gray rounded box .floating-assistant__user-bubble { - background: #f1f4f8; - border: 1px solid #e8eaed; + background: var(--fa-user-bubble-bg); + border: 1px solid var(--fa-user-bubble-border); border-radius: 10px; padding: 10px 14px; font-size: 13px; font-weight: 400; - color: #1d232f; + color: var(--fa-text); font-family: 'Optimo-Plain', sans-serif; line-height: 1.5; word-break: break-word; @@ -400,8 +479,8 @@ box-sizing: border-box; &--editing { - border-color: #2770ef; - background: #fff; + border-color: var(--fa-accent); + background: var(--fa-panel-bg); cursor: text; white-space: pre-wrap; } @@ -435,7 +514,7 @@ .floating-assistant__message-text { font-size: 13px; line-height: 1.6; - color: #1d232f; + color: var(--fa-text); word-break: break-word; font-family: 'Optimo-Plain', sans-serif; @@ -448,8 +527,8 @@ li { margin-bottom: 3px; } strong { font-weight: 600; } em { font-style: italic; } - a { color: #2770ef; text-decoration: underline; } - h1, h2, h3 { font-weight: 600; margin: 10px 0 4px; color: #1d232f; } + a { color: var(--fa-accent); text-decoration: underline; } + h1, h2, h3 { font-weight: 600; margin: 10px 0 4px; color: var(--fa-text); } h1 { font-size: 15px; } h2 { font-size: 14px; } h3 { font-size: 13px; } @@ -457,11 +536,11 @@ code { font-family: $font-family-code; font-size: 12px; - background: #f1f4f8; - color: #1d232f; + background: var(--fa-code-inline-bg); + color: var(--fa-text); border-radius: 3px; padding: 1px 5px; - border: 1px solid #e3e6eb; + border: 1px solid var(--fa-code-inline-border); } pre { @@ -486,7 +565,7 @@ gap: 5px; font-size: 13px; font-weight: 400; - color: #6b7280; + color: var(--fa-text-secondary); font-family: 'Optimo-Plain', sans-serif; cursor: default; user-select: none; @@ -513,12 +592,12 @@ border-radius: 4px; font-size: 11px; font-family: 'Optimo-Plain', sans-serif; - color: #a5acb9; + color: var(--fa-text-muted); transition: color 0.15s, background 0.15s; &:hover { - color: #1d232f; - background: #f1f4f8; + color: var(--fa-text); + background: var(--fa-surface); } &--copied { @@ -538,7 +617,7 @@ border-radius: 4px; opacity: 0.7; transition: opacity 0.15s, background 0.15s; - &:hover { opacity: 1; background: rgba(0,0,0,0.06); } + &:hover { opacity: 1; background: var(--fa-hover-overlay); } &.fa-feedback-btn--active { opacity: 1; } } @@ -552,7 +631,7 @@ .floating-assistant__loading-phase { font-size: 13px; - color: #5f6368; + color: var(--fa-text-secondary); font-family: 'Optimo-Plain', sans-serif; animation: fa-phase-in 0.4s ease-out forwards; } @@ -567,19 +646,19 @@ display: flex; align-items: center; gap: 6px; - background: #f1f4f8; + background: var(--fa-surface); border-radius: 8px; padding: 6px 8px 6px 10px; margin-bottom: 4px; - color: #5f6368; + color: var(--fa-text-secondary); - svg { flex-shrink: 0; color: #a5acb9; } + svg { flex-shrink: 0; color: var(--fa-text-muted); } } .floating-assistant__quote-text { flex: 1; font-size: 12px; - color: #5f6368; + color: var(--fa-text-secondary); font-family: 'Optimo-Plain', sans-serif; white-space: nowrap; overflow: hidden; @@ -621,6 +700,15 @@ border-radius: 10px 10px 0 0; } +// Code chrome for dark theme +#floating-assistant-root[data-theme='dark'] { + .fa-code-block { + background: var(--fa-bg); + pre { background: var(--fa-bg); } + } + .fa-code-header { background: var(--fa-surface-hover); } +} + .fa-code-lang { font-size: 12px; font-family: 'Optimo-Plain', sans-serif; @@ -632,7 +720,7 @@ .fa-code-copy { background: none; border: none; - color: #2770ef; + color: #71a1f4; cursor: pointer; font-size: 12px; font-family: 'Optimo-Plain', sans-serif; @@ -649,8 +737,8 @@ .floating-assistant__input-row { padding: 8px 12px 8px; flex-shrink: 0; - border-top: 1px solid rgba(0, 0, 0, 0.06); - background: rgba(255,255,255,0.6); + border-top: 1px solid var(--fa-input-row-border); + background: var(--fa-input-row-bg); backdrop-filter: blur(8px); } @@ -658,7 +746,7 @@ display: flex; flex-direction: column; gap: 6px; - background: #fff; + background: var(--fa-bg); border-radius: 12px; padding: 10px 10px 8px; cursor: text; @@ -671,7 +759,7 @@ inset: 0; border-radius: 12px; padding: 1.5px; - background: #d0d4db; + background: var(--fa-input-border-idle); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); @@ -718,15 +806,15 @@ font-size: 14px; font-family: 'Optimo-Plain', sans-serif; background: transparent; - color: #1d232f; + color: var(--fa-text); min-height: 28px; max-height: calc(14px * 1.5 * 4); // 4 lines at font-size 14px, line-height 1.5 overflow-y: auto; line-height: 1.5; - &::placeholder { color: #a5acb9; } + &::placeholder { color: var(--fa-text-muted); } scrollbar-width: thin; - scrollbar-color: #d0d4db transparent; + scrollbar-color: var(--fa-scrollbar) transparent; } .floating-assistant__input-buttons { @@ -740,15 +828,24 @@ width: 30px; height: 30px; border-radius: 50%; - border: 1px solid #e3e6eb; - background: #fff; + border: 1px solid var(--fa-border-strong); + background: var(--fa-btn-secondary-bg); cursor: pointer; display: flex; align-items: center; justify-content: center; flex-shrink: 0; transition: background 0.15s; - &:hover { background: #f1f4f8; } + &:hover { background: var(--fa-btn-secondary-bg-hover); } + &:active { background: var(--fa-btn-secondary-bg-pressed); } +} + +// Dark-mode-only icon tint +#floating-assistant-root[data-theme='dark'] { + .floating-assistant__reset-input, + .floating-assistant__edit-action-btn--edit { + --rd-sys-color-content-secondary: var(--rd-sys-color-background-inverse); + } } .floating-assistant__send { @@ -756,7 +853,7 @@ height: 30px; border-radius: 50%; border: none; - background: #2770ef; + background: var(--fa-accent); cursor: pointer; display: flex; align-items: center; @@ -764,7 +861,20 @@ flex-shrink: 0; transition: background 0.15s; &:disabled { opacity: 0.4; cursor: not-allowed; } - &:not(:disabled):hover { background: #1a5ccc; } + + // Default state uses the ambient --rd-sys-color-content-inverse as-is + // (white in light mode, near-black in dark mode against the lighter + // dark-mode button blue) — only hover/pressed need a local override for + // shades that token doesn't provide. + + &:not(:disabled):hover { + background: var(--fa-accent-hover); + --rd-sys-color-content-inverse: var(--fa-btn-primary-icon-hover); + } + &:not(:disabled):active { + background: var(--fa-btn-primary-pressed); + --rd-sys-color-content-inverse: var(--fa-btn-primary-icon-pressed); + } } .floating-assistant__stop { @@ -776,7 +886,7 @@ align-items: center; justify-content: center; flex-shrink: 0; - background: #2770ef; + background: var(--fa-accent); border:0px; color: #fff; transition: background 0.15s, border-color 0.15s; @@ -787,12 +897,12 @@ .floating-assistant__footer { padding: 6px 16px 12px; font-size: 11.5px; - color: #a5acb9; + color: var(--fa-text-muted); text-align: center; font-family: 'Optimo-Plain', sans-serif; a { - color: #2770ef; + color: var(--fa-accent); text-decoration: none; &:hover { text-decoration: underline; } } diff --git a/src/components/FloatingAssistant/index.tsx b/src/components/FloatingAssistant/index.tsx index 22edad90d..658f36daa 100644 --- a/src/components/FloatingAssistant/index.tsx +++ b/src/components/FloatingAssistant/index.tsx @@ -12,6 +12,9 @@ import { Message } from './types'; import { renderMarkdown, formatTimestamp, formatDuration, getPageId, stripMarkdown } from './helpers'; import { fetchSuggestedQuestions, streamAgentResponse, sendFeedback } from './api'; +// Matches 404_PAGE_TITLE in src/intl/en.json. +const NOT_FOUND_TITLE = 'Not found'; + const SparkleIcon = () => ( ); @@ -47,6 +50,18 @@ const FloatingAssistant: React.FC = () => { const [isTutorialsPage, setIsTutorialsPage] = useState( () => typeof window !== 'undefined' && isTutorialsPath(window.location.pathname), ); + // The 404 page has no fixed pathname to match against (it renders for + // whatever bogus URL the user hit), so detect it via document.title + // instead. NOTE: a DOM marker (id) doesn't work here — in production, + // Gatsby prefetches/pre-mounts the 404 page's component into the live + // DOM in the background (for instant fallback on broken links) even + // while a completely different, valid page is showing, so + // getElementById('page-404') can be true on any page. document.title + // isn't affected by that background mount, only by the page actually + // being rendered. + const [isNotFoundPage, setIsNotFoundPage] = useState( + () => typeof document !== 'undefined' && document.title === NOT_FOUND_TITLE, + ); const { isOpen, setIsOpen, @@ -269,6 +284,52 @@ const FloatingAssistant: React.FC = () => { return () => window.removeEventListener('gatsby-route-update', handler as EventListener); }, []); + // This widget mounts into its own React root appended directly to + // document.body (see gatsby-browser.js), outside #wrapper/#docsModal, so + // it can't inherit the site's data-theme custom properties. Mirror the + // site's current theme onto our own root's data-theme attribute instead, + // so CSS here can key off #floating-assistant-root[data-theme='dark']. + useEffect(() => { + const themeRoot = document.getElementById('floating-assistant-root'); + const setTheme = (theme: 'dark' | 'light') => { + // Guard against redundant writes — themeRoot lives inside document.body, + // so an unconditional setAttribute here would itself be a mutation that + // a body-wide observer could pick back up, looping forever. + if (themeRoot && themeRoot.getAttribute('data-theme') !== theme) { + themeRoot.setAttribute('data-theme', theme); + } + }; + + let attrObserver: MutationObserver | null = null; + + // Watches the specific #wrapper/#docsModal element for data-theme flips + // (e.g. the user toggling dark mode) — scoped to that one element only, + // so it never observes themeRoot's own attribute writes above. + const watchThemedEl = () => { + const themedEl = document.getElementById('wrapper') || document.getElementById('docsModal'); + if (!themedEl) return; + setTheme(themedEl.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'); + attrObserver?.disconnect(); + attrObserver = new MutationObserver(() => { + setTheme(themedEl.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'); + }); + attrObserver.observe(themedEl, { attributes: true, attributeFilter: ['data-theme'] }); + }; + + watchThemedEl(); + + // #wrapper/#docsModal can be unmounted/remounted on client-side route + // changes — re-attach the attribute observer whenever that happens. + // childList-only, so this never fires from themeRoot's attribute writes. + const bodyObserver = new MutationObserver(watchThemedEl); + bodyObserver.observe(document.body, { childList: true, subtree: true }); + + return () => { + attrObserver?.disconnect(); + bodyObserver.disconnect(); + }; + }, []); + useEffect(() => { const handler = (e: CustomEvent<{ location: Location }>) => { setIsTutorialsPage(isTutorialsPath(e.detail.location.pathname)); @@ -277,6 +338,12 @@ const FloatingAssistant: React.FC = () => { return () => window.removeEventListener('gatsby-route-update', handler as EventListener); }, []); + useEffect(() => { + const handler = () => setIsNotFoundPage(document.title === NOT_FOUND_TITLE); + window.addEventListener('gatsby-route-update', handler as EventListener); + return () => window.removeEventListener('gatsby-route-update', handler as EventListener); + }, []); + useEffect(() => { const handler = (e: CustomEvent<{ quotedText: string }>) => { setQuotedText(e.detail.quotedText); @@ -427,6 +494,7 @@ const FloatingAssistant: React.FC = () => { if (pageId === CUSTOM_PAGE_ID.API_PLAYGROUND) return null; if (isTutorialsPage) return null; + if (isNotFoundPage) return null; return ( <> @@ -455,7 +523,7 @@ const FloatingAssistant: React.FC = () => { SpotterCode @@ -579,7 +647,7 @@ const FloatingAssistant: React.FC = () => { ) : ( i === messages.map((m, idx) => m.role === 'user' ? idx : -1).filter(x => x >= 0).pop() && !isLoading && ( - ) @@ -685,7 +753,7 @@ const FloatingAssistant: React.FC = () => { aria-label="Reset conversation" disabled={messages.length === 0 && !input.trim() && !quotedText} > - + {isLoading ? (