diff --git a/gatsby-config.js b/gatsby-config.js
index 166faf087..efad469bf 100644
--- a/gatsby-config.js
+++ b/gatsby-config.js
@@ -192,6 +192,7 @@ module.exports = {
.queries,
// for testing add dryRun as true,
// dryRun: true,
+ continueOnFailure: !process.env.ALGOLIA_ADMIN_KEY,
},
},
{
diff --git a/gatsby-node.js b/gatsby-node.js
index 3cb3567e4..98a9cf3a9 100644
--- a/gatsby-node.js
+++ b/gatsby-node.js
@@ -3,14 +3,123 @@ const {
DOC_NAV_PAGE_ID,
NOT_FOUND_PAGE_ID,
VERSION_DROPDOWN,
+ SITE_URL,
+ LLMS_SECTIONS,
} = require('./src/configs/doc-configs');
const { getDocLinkFromEdge } = require('./src/utils/gatsby-utils.js');
-exports.onPostBuild = () => {
+/* ── Build-time Markdown generation ───────────────────────────────────────
+ * For every asciidoc node, convert the already-generated HTML to clean
+ * Markdown using cheerio (DOM pre-processing) + turndown (HTML→MD).
+ * The result is stored as `fields.markdownBody` on each node and exposed
+ * in GraphQL so CopyPageDropdown can use it instead of scraping the DOM.
+ */
+exports.onCreateNode = ({ node, actions }) => {
+ if (node.internal.type !== 'Asciidoc') return;
+
+ const { createNodeField } = actions;
+ const TurndownService = require('turndown');
+ const cheerio = require('cheerio');
+
+ const html = node.html || '';
+ const title = node.document?.title || node.pageAttributes?.title || '';
+
+ /* Load HTML into cheerio for pre-processing */
+ const $ = cheerio.load(html, { decodeEntities: false });
+
+ /* Remove anchor icon links that Asciidoctor injects next to headings */
+ $('a.anchor').remove();
+
+ /* Remove the embedded TOC — it adds noise to Markdown */
+ $('#toc').remove();
+
+ /* Convert admonition tables to readable text blocks */
+ $('.admonitionblock').each((_, el) => {
+ const type = $(el).attr('class').match(/\b(note|tip|warning|caution|important)\b/i)?.[1]?.toUpperCase() || 'NOTE';
+ const content = $(el).find('td.content').text().trim();
+ $(el).replaceWith(`
${type}: ${content}
`);
+ });
+
+ /* Get the cleaned HTML */
+ const cleanedHtml = $('body').html() || '';
+
+ /* Configure turndown */
+ const td = new TurndownService({
+ headingStyle: 'atx',
+ bulletListMarker: '-',
+ codeBlockStyle: 'fenced',
+ fence: '```',
+ });
+
+ /* GFM table plugin — renders tables as proper Markdown pipe tables */
+ const { tables } = require('turndown-plugin-gfm');
+ td.use(tables);
+
+ const markdownBody = td.turndown(cleanedHtml);
+
+ createNodeField({
+ node,
+ name: 'markdownBody',
+ value: markdownBody,
+ });
+};
+
+exports.onPostBuild = async ({ graphql, reporter }) => {
fsExtra.copyFileSync(
`${__dirname}/robots.txt`,
`${__dirname}/public/robots.txt`,
);
+
+ try {
+ const result = await graphql(`
+ query {
+ allAsciidoc {
+ edges {
+ node {
+ document { title }
+ pageAttributes { pageid }
+ }
+ }
+ }
+ }
+ `);
+
+ if (result.errors) {
+ reporter.warn(`llms.txt generation: GraphQL errors — ${JSON.stringify(result.errors)}`);
+ return;
+ }
+
+ const pageMap = {};
+ result.data.allAsciidoc.edges.forEach(({ node }) => {
+ const pageid = node.pageAttributes?.pageid;
+ const title = node.document?.title;
+ if (pageid && title) pageMap[pageid] = title;
+ });
+
+ const lines = [
+ '# ThoughtSpot Developer Documentation',
+ '',
+ '> Developer documentation for ThoughtSpot Embedded — tools, APIs, and SDKs for embedding ThoughtSpot analytics into your applications.',
+ '',
+ ];
+
+ for (const section of LLMS_SECTIONS) {
+ lines.push(`## ${section.label}`);
+ for (const pageId of section.pageIds) {
+ const title = pageMap[pageId];
+ if (title) lines.push(`- [${title}](${SITE_URL}/${pageId})`);
+ }
+ lines.push('');
+ }
+
+ fsExtra.writeFileSync(
+ `${__dirname}/public/llms.txt`,
+ lines.join('\n'),
+ );
+ reporter.info(`llms.txt generated with ${Object.keys(pageMap).length} pages`);
+ } catch (err) {
+ reporter.warn(`llms.txt generation failed: ${err.message}`);
+ }
};
exports.createPages = async function ({ actions, graphql }) {
const { data } = await graphql(`
@@ -39,12 +148,23 @@ exports.createPages = async function ({ actions, graphql }) {
`);
const namePageIdMap = {};
+ // Collect per-category nav HTMLs keyed by category name (pageid minus 'nav-' prefix)
+ const navMap = {};
+ const NAV_PARTIAL_PREFIX = 'nav-';
+
data.allAsciidoc.edges.forEach((e) => {
const {
sourceInstanceName: sourceName,
relativePath: relPath,
} = e.node.parent;
const pageId = e.node.pageAttributes.pageid;
+
+ // Collect nav-* files into the navMap (not content pages)
+ if (pageId && pageId.startsWith(NAV_PARTIAL_PREFIX)) {
+ navMap[pageId.slice(NAV_PARTIAL_PREFIX.length)] = e.node.html;
+ return;
+ }
+
if (sourceName === 'tutorials') {
const relPathSplit = relPath.split('/');
const pageIdSplit = pageId.split('__');
@@ -66,13 +186,16 @@ exports.createPages = async function ({ actions, graphql }) {
data.allAsciidoc.edges.forEach((edge) => {
const { pageid: pageId } = edge.node.pageAttributes;
+ // Skip nav partial files — they are sidebar data, not content pages
+ if (pageId && pageId.startsWith(NAV_PARTIAL_PREFIX)) return;
+
const docPath = getDocLinkFromEdge(edge);
actions.createPage({
path: docPath,
component: require.resolve(
'./src/components/DevDocTemplate/index.tsx',
),
- context: { pageId, navId: DOC_NAV_PAGE_ID, namePageIdMap },
+ context: { pageId, navId: DOC_NAV_PAGE_ID, navMap, namePageIdMap },
});
if (pageId === 'introduction') {
@@ -81,7 +204,7 @@ exports.createPages = async function ({ actions, graphql }) {
component: require.resolve(
'./src/components/DevDocTemplate/index.tsx',
),
- context: { pageId, navId: DOC_NAV_PAGE_ID, namePageIdMap },
+ context: { pageId, navId: DOC_NAV_PAGE_ID, navMap, namePageIdMap },
});
}
});
diff --git a/modules/ROOT/pages/ai-integration-options.adoc b/modules/ROOT/pages/ai-integration-options.adoc
index 5e67530b7..ec760fd73 100644
--- a/modules/ROOT/pages/ai-integration-options.adoc
+++ b/modules/ROOT/pages/ai-integration-options.adoc
@@ -1,4 +1,4 @@
-= ThoughtSpot AI analytics integration
+= AI analytics integration
:toc: true
:toclevels: 3
diff --git a/modules/ROOT/pages/common/nav-embedding.adoc b/modules/ROOT/pages/common/nav-embedding.adoc
new file mode 100644
index 000000000..5632e6cbd
--- /dev/null
+++ b/modules/ROOT/pages/common/nav-embedding.adoc
@@ -0,0 +1,177 @@
+
+:page-pageid: nav-embedding
+:page-description: Embedding navigation
+
+[navSection]
+
+[.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}}/embed-spotter-agent[Embed Spotter Agent]
+* link:{{navprefix}}/embed-liveboard[Embed Analytics]
+** link:{{navprefix}}/embed-liveboard[Embed a Liveboard]
+** 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}}/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}}/react-app-embed[Embed with React components]
+
+[.sidebar-title]
+Embed ThoughtSpot in a mobile app
+
+* link:{{navprefix}}/mobile-embed[Overview]
+* link:{{navprefix}}/embed-ts-mobile-react-native[React Native SDK]
+* link:{{navprefix}}/embed-ts-flutter[Flutter embed SDK]
+* link:{{navprefix}}/embed-ts-swift[Swift Embed SDK]
+* link:{{navprefix}}/embed-ts-android[Android Embed SDK]
+
+[.sidebar-title]
+Embed without SDK
+
+** link:{{navprefix}}/embed-without-sdk[Embed without SDK]
+** link:{{navprefix}}/custom-viz-rest-api[Create a custom visualization]
+
+[.sidebar-title]
+Customize and integrate
+
+* link:{{navprefix}}/style-customization[Customize UI layout and styles]
+** link:{{navprefix}}/customize-style[Customize basic styles]
+** link:{{navprefix}}/custom-css[CSS customization framework]
+** link:{{navprefix}}/theme-builder-doc[Theme builder]
+** link:{{navprefix}}/customize-icons[Customize icons]
+** link:{{navprefix}}/customize-text[Customize text strings]
+** link:{{navprefix}}/css-variables-reference[CSS variables reference]
+
+* link:{{navprefix}}/filters-overview[Filters types and application layers]
+** link:{{navprefix}}/runtime-overrides[Runtime overrides]
+** link:{{navprefix}}/runtime-filters[Runtime filters]
+** link:{{navprefix}}/runtime-params[Runtime Parameters]
+* link:{{navprefix}}/action-config[Customize menus]
+** link:{{navprefix}}/actions[Action IDs in the SDK]
+* link:{{navprefix}}/events-app-integration[Events and app interactions]
+** link:{{navprefix}}/embed-events[Using embed events]
+** link:{{navprefix}}/host-events[Using host events]
+** link:{{navprefix}}/context-aware-event-routing[Context-based execution of host events]
+** link:{{navprefix}}/hostEventsV2-migration[Migrating from Host Event v1 to Host Events v2 framework]
+** link:{{navprefix}}/handling-embed-errors[Handling embed errors]
+** link:{{navprefix}}/api-search-intercept[API intercept and data fetch requests]
+
+* link:{{navprefix}}/custom-action-intro[Custom actions]
+** link:{{navprefix}}/customize-actions[Custom actions through the UI]
+*** link:{{navprefix}}/custom-action-url[URL actions]
+*** link:{{navprefix}}/custom-action-callback[Callback actions]
+*** link:{{navprefix}}/edit-custom-action[Set the position of a custom action]
+*** link:{{navprefix}}/add-action-viz[Add a local action to a visualization]
+*** link:{{navprefix}}/add-action-worksheet[Add a local action to a model]
+** link:{{navprefix}}/code-based-custom-action[Code based custom actions]
+** link:{{navprefix}}/custom-action-payload[Callback response payload]
+
+* link:{{navprefix}}/customize-links[Customize links]
+* 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]
+** link:{{navprefix}}/prerender[Prerender components]
+** link:{{navprefix}}/lazy-load-fullHeight[Full height and lazy loading options]
+** link:{{navprefix}}/prefetch[Prefetch static resources]
+* link:{{navprefix}}/troubleshoot-errors[Troubleshoot errors]
+
+[.sidebar-title]
+Authentication and data security
+
+* link:{{navprefix}}/embed-auth[Authentication]
+** link:{{navprefix}}/trusted-auth[Trusted authentication]
+*** link:{{navprefix}}/trusted-auth-secret-key[Secret key management]
+*** link:{{navprefix}}/trusted-auth-sdk[Front-end trusted authentication integration]
+*** link:{{navprefix}}/trusted-auth-token-request-service[Token request service]
+*** link:{{navprefix}}/trusted-auth-troubleshoot[Troubleshoot trusted authentication]
+** link:{{navprefix}}/saml-sso[SAML SSO authentication]
+** link:{{navprefix}}/oidc-auth[OpenID Connect authentication]
+** link:{{navprefix}}/just-in-time-provisioning[Just-in-time provisioning]
+* link:{{navprefix}}/security-settings[Security settings]
+
+* link:{{navprefix}}/embed-object-access[Authorization]
+** link:{{navprefix}}/access-control-sharing[Access control and sharing]
+** link:{{navprefix}}/privileges-and-roles[Privileges and Roles]
+** link:{{navprefix}}/data-security[Data security]
+*** link:{{navprefix}}/rls-rules[RLS Rules]
+*** link:{{navprefix}}/abac-via-rls-variables[ABAC via RLS with variables]
+*** link:{{navprefix}}/jwt-abac-migration-guide[ABAC JWT migration guide]
+**** link:{{navprefix}}/jwt-filter-parameters-rules-migration-guide[JWT ABAC with filter rules -> ABAC via RLS]
+**** link:{{navprefix}}/jwt-abac-beta-migration-guide[JWT ABAC beta implementation -> ABAC via RLS]
+*** link:{{navprefix}}/abac-user-parameters[ABAC via JWT with filter rules and parameters]
+* link:{{navprefix}}/selective-user-access[User access]
+* 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]
+** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-01[01 - Overview]
+** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-02[02 - Set up for course]
+** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-03[03 - Security setup]
+** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-04[04 - Start coding]
+** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-05[05 - Embed Search]
+** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-06[06 - Embed Natural Language Search]
+** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-07[07 - Embed Liveboard]
+** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-08[08 - Embed Visualization]
+** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-09[09 - Embed full application]
+** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-10[10 - Style embedded app]
+** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-11[11 - Course summary]
+** link:{{navprefix}}/tutorials/style-customization/tutorial[Style customization]
+* link:{{navprefix}}/tutorials/react-components/intro[React components]
+** link:{{navprefix}}/tutorials/react-components/lesson-01[01 - Initialize Visual Embed SDK]
+** link:{{navprefix}}/tutorials/react-components/lesson-02[02 - ThoughtSpot component pages]
+** link:{{navprefix}}/tutorials/react-components/lesson-03[03 - Menus and navigation elements]
+** link:{{navprefix}}/tutorials/react-components/lesson-04[04 - Event handling]
+
+
+[.sidebar-title]
+Reference guides and changelog
+
+* +++Visual Embed Playground+++
+* link:{{navprefix}}/VisualEmbedSdk[Visual Embed SDK Reference]
+include::generated/typedoc/CustomSideNav.adoc[]
+** Custom styles
+*** [.typedoc-Interface]#link:{{navprefix}}/Interface_CustomStyles[CustomStyles]#
+*** [.typedoc-Interface]#link:{{navprefix}}/Interface_CustomisationsInterface[CustomisationsInterface]#
+*** [.typedoc-Interface]#link:{{navprefix}}/Interface_customCssInterface[customCssInterface]#
+*** [.typedoc-Interface]#link:{{navprefix}}/Interface_CustomCssVariables[customCssVariables]#
+** Runtime filters
+*** [.typedoc-Interface]#link:{{navprefix}}/Interface_RuntimeFilter[RuntimeFilter]#
+*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_RuntimeFilterOp[RuntimeFilterOp]#
+** Others
+*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_Action[Action]#
+*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_ContextMenuTriggerOptions[ContextMenuTriggerOptions]#
+*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_DataSourceVisualMode[DataSourceVisualMode]#
+*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_Page[Page]#
+*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_PrefetchFeatures[PrefetchFeatures]#
+*** [.typedoc-Function]#link:{{navprefix}}/Function_executeTML[executeTML]#
+*** [.typedoc-Function]#link:{{navprefix}}/Function_exportTML[exportTML]#
+* link:{{navprefix}}/embed-sdk-changelog[Changelog]
+** link:{{navprefix}}/embed-sdk-changelog[Visual Embed SDK]
+** link:{{navprefix}}/mobile-sdk-changelog[Mobile Embed SDK]
+
+[.sidebar-title]
+Additional resources
+
+* link:{{navprefix}}/embed-ts[About ThoughtSpot embedding]
+* link:{{navprefix}}/get-started-tse[Embed licenses]
+* link:{{navprefix}}/license-feature-matrix[Feature matrix]
+* link:{{navprefix}}/faqs[FAQs]
+* link:{{navprefix}}/code-samples[Code samples]
+* link:https://codesandbox.io/s/big-tse-react-demo-i4g9xi[React CodeSandbox, window=_blank]
+* link:https://codesandbox.io/s/graphqlcookieembed-wf4fk9?file=/src/App.js:418-426[GraphQL CodeSandbox, window=_blank]
diff --git a/modules/ROOT/pages/common/nav-mcp-server.adoc b/modules/ROOT/pages/common/nav-mcp-server.adoc
new file mode 100644
index 000000000..d40f131d7
--- /dev/null
+++ b/modules/ROOT/pages/common/nav-mcp-server.adoc
@@ -0,0 +1,32 @@
+
+:page-pageid: nav-mcp-server
+:page-description: MCP Server navigation
+
+[navSection]
+
+[.sidebar-title]
+ThoughtSpot MCP server
+
+* link:{{navprefix}}/mcp-integration[Overview]
+** link:{{navprefix}}/mcp-server-spotter3[MCP Server with Spotter 3]
+** link:{{navprefix}}/mcp-server-legacy[Legacy MCP Server architecture and tools]
+* link:{{navprefix}}/connect-mcp-server-to-clients[Connecting MCP Server to MCP clients]
+* link:{{navprefix}}/custom-chatbot-integration-mcp[Integrating MCP Server in a custom app]
+
+[.sidebar-title]
+MCP tools reference
+
+* link:{{navprefix}}/mcp-tool-reference[Overview]
+* link:{{navprefix}}/mcp-tool-reference-spotter3[MCP tool reference (Spotter 3)]
+* link:{{navprefix}}/mcp-tool-reference-spotter3[MCP tool reference (legacy version)]
+
+[.sidebar-title]
+Related SDK components
+
+* [.typedoc-Function]#link:{{navprefix}}/Function_startAutoMCPFrameRenderer[startAutoMCPFrameRenderer]#
+* [.typedoc-Interface]#link:{{navprefix}}/Interface_AutoMCPFrameRendererViewConfig[AutoMCPFrameRendererViewConfig]#
+
+[.sidebar-title]
+MCP Server release notes
+
+* link:{{navprefix}}/mcp-server-changelog[MCP Server changelog]
diff --git a/modules/ROOT/pages/common/nav-rest-api.adoc b/modules/ROOT/pages/common/nav-rest-api.adoc
new file mode 100644
index 000000000..a9fec3165
--- /dev/null
+++ b/modules/ROOT/pages/common/nav-rest-api.adoc
@@ -0,0 +1,96 @@
+
+:page-pageid: nav-rest-api
+:page-description: REST API navigation
+
+[navSection]
+
+[.sidebar-title]
+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]
+* link:{{navprefix}}/rest-apiv2-reference[REST API v2.0 Reference]
+** 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}}/spotter-api[Spotter APIs]
+*** link:{{navprefix}}/spotter-agent-apis[AI APIs (Spotter Agent and Spotter 3)]
+*** link:{{navprefix}}/spotter-apis-classic[AI APIs (Spotter Classic) ^BETA^]
+*** link:{{navprefix}}/spotter-coaching-apis[Spotter coaching APIs ^BETA^]
+** link:{{navprefix}}/audit-logs[Audit logs]
+** link:{{navprefix}}/tml[TML]
+** link:{{navprefix}}/collections[Collections ^BETA^]
+** link:{{navprefix}}/connections[Connections]
+** link:{{navprefix}}/connection-config[Connection configuration]
+** link:{{navprefix}}/runtime-sort[Runtime sorting]
+
+
+[.sidebar-title]
+REST API SDK
+
+* link:{{navprefix}}/rest-api-sdk[Overview]
+* link:{{navprefix}}/rest-api-sdk-typescript[TypeScript SDK]
+* link:{{navprefix}}/rest-api-sdk-java[Java SDK]
+* link:{{navprefix}}/rest-apiv2-js[REST API v2.0 in JavaScript]
+
+[.sidebar-title]
+Webhooks
+
+* link:{{navprefix}}/webhooks[Overview]
+* link:{{navprefix}}/webhooks-comm-channel[Configure and monitor webhook communication channels]
+* link:{{navprefix}}/webhooks-s3-integration[Deliver Liveboard reports to AWS S3 Storage]
+* link:{{navprefix}}/webhooks-lb-schedule[Deliver Liveboard reports to external application]
+* link:{{navprefix}}/webhooks-lb-payload[Webhook response payload]
+* link:{{navprefix}}/webhooks-kpi[Webhook for KPI alerts]
+
+[.sidebar-title]
+REST API Tutorials
+
+* link:{{navprefix}}/tutorials/rest-api/intro[REST API Tutorials]
+* 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}}/rest-api-reference[REST API v1 Reference]
+** link:{{navprefix}}/orgs-api[Orgs API]
+** link:{{navprefix}}/user-api[User API]
+** link:{{navprefix}}/group-api[Group API]
+** link:{{navprefix}}/role-api[Role API]
+** link:{{navprefix}}/session-api[Session API]
+** link:{{navprefix}}/connections-api[Data connection API]
+** link:{{navprefix}}/metadata-api[Metadata API]
+** link:{{navprefix}}/admin-api[Admin API]
+** link:{{navprefix}}/tml-api[TML API]
+** link:{{navprefix}}/dependent-objects-api[Dependent objects API]
+** link:{{navprefix}}/search-data-api[Search data API]
+** link:{{navprefix}}/liveboard-data-api[Liveboard data API]
+** link:{{navprefix}}/liveboard-export-api[Liveboard export API]
+** link:{{navprefix}}/security-api[Security API]
+** link:{{navprefix}}/logs-api[Audit logs API]
+** link:{{navprefix}}/materialization-api[Materialization API]
+** link:{{navprefix}}/database-api[Database API]
+** link:{{navprefix}}/rest-v1-changelog[REST API v1 changelog]
+** link:{{navprefix}}/v1v2-comparison[REST v1 and v2.0 comparison]
+
+
+//** link:{{navprefix}}/graphql-guide[GraphQL API ^Beta^]
+
+
+
+
+
+
diff --git a/modules/ROOT/pages/common/nav-spottercode.adoc b/modules/ROOT/pages/common/nav-spottercode.adoc
new file mode 100644
index 000000000..b60c85c31
--- /dev/null
+++ b/modules/ROOT/pages/common/nav-spottercode.adoc
@@ -0,0 +1,12 @@
+
+:page-pageid: nav-spottercode
+:page-description: SpotterCode navigation
+
+[navSection]
+
+[.sidebar-title]
+SpotterCode agent
+
+* link:{{navprefix}}/SpotterCode[SpotterCode for IDEs]
+* link:{{navprefix}}/integrate-SpotterCode[Integrating SpotterCode]
+* link:{{navprefix}}/spottercode-prompting-guide[SpotterCode prompting guide]
diff --git a/modules/ROOT/pages/common/nav-tutorials.adoc b/modules/ROOT/pages/common/nav-tutorials.adoc
new file mode 100644
index 000000000..b7933f53d
--- /dev/null
+++ b/modules/ROOT/pages/common/nav-tutorials.adoc
@@ -0,0 +1,29 @@
+
+:page-pageid: nav-tutorials
+:page-description: Tutorials navigation
+
+[navSection]
+
+* link:{{navprefix}}/tutorials/tutorials-overview[Tutorials]
+** link:{{navprefix}}/tutorials/tse-fundamentals/intro[Embedding Fundamentals]
+*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-01[01 - Overview]
+*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-02[02 - Set up for course]
+*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-03[03 - Security setup]
+*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-04[04 - Start coding]
+*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-05[05 - Embed Search]
+*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-06[06 - Embed Natural Language Search]
+*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-07[07 - Embed Liveboard]
+*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-08[08 - Embed Visualization]
+*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-09[09 - Embed full application]
+*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-10[10 - Style embedded app]
+*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-11[11 - Course summary]
+** link:{{navprefix}}/tutorials/style-customization/tutorial[Style customization]
+** link:{{navprefix}}/tutorials/react-components/intro[React components]
+*** link:{{navprefix}}/tutorials/react-components/lesson-01[01 - Initialize Visual Embed SDK]
+*** link:{{navprefix}}/tutorials/react-components/lesson-02[02 - ThoughtSpot component pages]
+*** link:{{navprefix}}/tutorials/react-components/lesson-03[03 - Menus and navigation elements]
+*** link:{{navprefix}}/tutorials/react-components/lesson-04[04 - Event handling]
+
+*** link:{{navprefix}}/tutorials/rest-api/lesson-04[04 - Event handling]
+** Spotter
+*** link:{{navprefix}}/tutorials/spotter/integrate-into-chatbot[Integrate Spotter into your Chatbot]
diff --git a/modules/ROOT/pages/common/nav.adoc b/modules/ROOT/pages/common/nav.adoc
index 9211d0470..a3af2a9a6 100644
--- a/modules/ROOT/pages/common/nav.adoc
+++ b/modules/ROOT/pages/common/nav.adoc
@@ -4,255 +4,97 @@
[navSection]
-* link:{{navprefix}}/ask-docs[AskDocs ^Beta^]
+[.sidebar-title]
+Release notes and changelogs
-* link:{{navprefix}}/whats-new[What's New]
-** link:{{navprefix}}/whats-new[New features]
-*** link:{{navprefix}}/fixed-issues[Fixed issues]
-*** link:{{navprefix}}/known-issues[Known Issues]
+* 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[MCP Server changelog]
+* link:{{navprefix}}/deprecated-features[Deprecation announcements]
+[.sidebar-title]
+Live Playgrounds
-** link:{{navprefix}}/embed-sdk-changelog[SDK and API changelog]
-*** link:{{navprefix}}/embed-sdk-changelog[Visual Embed changelog]
-*** link:{{navprefix}}/mobile-sdk-changelog[Mobile Embed SDK changelog]
-*** link:{{navprefix}}/rest-v2-changelog[REST API v2 changelog]
-*** link:{{navprefix}}/rest-v1-changelog[REST API v1 changelog]
-** link:{{navprefix}}/deprecated-features[Deprecation announcements]
+* +++Visual Embed Playground+++
+** link:{{navprefix}}/dev-playground[How to use]
-* Live Playgrounds
-** +++Visual Embed Playground+++
-** link:{{navprefix}}/restV2-playground?apiResourceId=http%2Fgetting-started%2Fintroduction[REST API v2 Playground]
-** link:{{navprefix}}/graphql-play-ground[GraphQL Playground]
-** +++REST API v1 Playground+++
-** link:{{navprefix}}/theme-builder[Theme Builder]
-** link:{{navprefix}}/spotdev-portal[How to use]
-*** link:{{navprefix}}/dev-playground[Visual Embed Playground]
-*** link:{{navprefix}}/graphql-playground[GraphQL Playground]
-*** link:{{navprefix}}/rest-playground[REST API Playground]
+* link:{{navprefix}}/restV2-playground?apiResourceId=http%2Fgetting-started%2Fintroduction[REST API v2 Playground]
+** link:{{navprefix}}/rest-playground[How to use]
+//** link:{{navprefix}}/graphql-play-ground[GraphQL Playground]
+//** +++REST API v1 Playground+++
+* link:{{navprefix}}/theme-builder[Theme Builder]
+** link:{{navprefix}}/theme-builder-doc[How to use]
-* link:{{navprefix}}/tutorials/tutorials-overview[Tutorials]
-** link:{{navprefix}}/tutorials/tse-fundamentals/intro[Embedding Fundamentals]
-*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-01[01 - Overview]
-*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-02[02 - Set up for course]
-*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-03[03 - Security setup]
-*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-04[04 - Start coding]
-*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-05[05 - Embed Search]
-*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-06[06 - Embed Natural Language Search]
-*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-07[07 - Embed Liveboard]
-*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-08[08 - Embed Visualization]
-*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-09[09 - Embed full application]
-*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-10[10 - Style embedded app]
-*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-11[11 - Course summary]
-** link:{{navprefix}}/tutorials/style-customization/tutorial[Style customization]
-** link:{{navprefix}}/tutorials/react-components/intro[React components]
-*** link:{{navprefix}}/tutorials/react-components/lesson-01[01 - Initialize Visual Embed SDK]
-*** link:{{navprefix}}/tutorials/react-components/lesson-02[02 - ThoughtSpot component pages]
-*** link:{{navprefix}}/tutorials/react-components/lesson-03[03 - Menus and navigation elements]
-*** link:{{navprefix}}/tutorials/react-components/lesson-04[04 - Event handling]
-** link:{{navprefix}}/tutorials/rest-api/intro[REST API]
-*** 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]
-*** link:{{navprefix}}/tutorials/rest-api/lesson-04[04 - Event handling]
-** Spotter
-*** link:{{navprefix}}/tutorials/spotter/integrate-into-chatbot[Integrate Spotter into your Chatbot]
-* link:{{navprefix}}/getting-started[Embed ThoughtSpot]
-** link:{{navprefix}}/getting-started[Quickstart Guide]
-** link:{{navprefix}}/tsembed[Embed ThoughtSpot in Web app]
-*** Embed analytics
-**** link:{{navprefix}}/embed-liveboard[Embed a Liveboard]
-**** link:{{navprefix}}/embed-a-viz[Embed a visualization]
-*** link:{{navprefix}}/embed-ai-search-analytics[Embed AI Search and Analytics]
-**** link:{{navprefix}}/embed-spotter[Embed Spotter experience]
-**** link:{{navprefix}}/embed-spotter-agent[Embed Spotter Agent]
-*** 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}}/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}}/react-app-embed[Embed with React components]
-** link:{{navprefix}}/mobile-embed[Embed ThoughtSpot in a mobile app]
-*** link:{{navprefix}}/embed-ts-mobile-react-native[React Native SDK]
-*** link:{{navprefix}}/embed-ts-flutter[Flutter embed SDK]
-*** link:{{navprefix}}/embed-ts-swift[Swift Embed SDK]
-*** link:{{navprefix}}/embed-ts-android[Android Embed SDK]
-
-** Customize and integrate
-*** link:{{navprefix}}/style-customization[Customize UI layout and styles]
-**** link:{{navprefix}}/customize-style[Customize basic styles]
-**** link:{{navprefix}}/custom-css[CSS customization framework]
-***** link:{{navprefix}}/css-variables-reference[CSS variables reference]
-***** link:{{navprefix}}/customize-icons[Customize icons]
-***** link:{{navprefix}}/customize-text[Customize text strings]
-***** link:{{navprefix}}/theme-builder-doc[Theme builder]
-
-*** link:{{navprefix}}/filters-overview[Filters types and application layers]
-**** link:{{navprefix}}/runtime-overrides[Runtime overrides]
-**** link:{{navprefix}}/runtime-filters[Runtime filters]
-**** link:{{navprefix}}/runtime-params[Runtime Parameters]
-
-*** link:{{navprefix}}/action-config[Customize menus]
-**** link:{{navprefix}}/actions[Action IDs in the SDK]
-*** link:{{navprefix}}/events-app-integration[Events and app interactions]
-**** link:{{navprefix}}/embed-events[Using embed events]
-**** link:{{navprefix}}/host-events[Using host events]
-**** link:{{navprefix}}/context-aware-event-routing[Context-based execution of host events]
-**** link:{{navprefix}}/hostEventsV2-migration[Migrating from Host Event v1 to Host Events v2 framework]
-**** link:{{navprefix}}/handling-embed-errors[Handling embed errors]
-**** link:{{navprefix}}/api-search-intercept[API intercept and data fetch requests]
-*** link:{{navprefix}}/custom-action-intro[Custom actions]
-**** link:{{navprefix}}/customize-actions[Custom actions through the UI]
-***** link:{{navprefix}}/custom-action-url[URL actions]
-***** link:{{navprefix}}/custom-action-callback[Callback actions]
-***** link:{{navprefix}}/edit-custom-action[Set the position of a custom action]
-***** link:{{navprefix}}/add-action-viz[Add a local action to a visualization]
-***** link:{{navprefix}}/add-action-worksheet[Add a local action to a model]
-**** link:{{navprefix}}/code-based-custom-action[Code based custom actions]
-**** link:{{navprefix}}/custom-action-payload[Callback response payload]
-*** link:{{navprefix}}/customize-links[Customize links]
-*** 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}}/security-settings[Security settings]
-** link:{{navprefix}}/embed-auth[Authentication]
-*** link:{{navprefix}}/trusted-auth[Trusted authentication]
-**** link:{{navprefix}}/trusted-auth-secret-key[Secret key management]
-**** link:{{navprefix}}/trusted-auth-sdk[Front-end trusted authentication integration]
-**** link:{{navprefix}}/trusted-auth-token-request-service[Token request service]
-**** link:{{navprefix}}/trusted-auth-troubleshoot[Troubleshoot trusted authentication]
-*** link:{{navprefix}}/saml-sso[SAML SSO authentication]
-*** link:{{navprefix}}/oidc-auth[OpenID Connect authentication]
-*** link:{{navprefix}}/just-in-time-provisioning[Just-in-time provisioning]
-** link:{{navprefix}}/embed-object-access[Authorization]
-*** link:{{navprefix}}/access-control-sharing[Access control and sharing]
-*** link:{{navprefix}}/privileges-and-roles[Privileges and Roles]
-*** link:{{navprefix}}/data-security[Data security]
-**** link:{{navprefix}}/rls-rules[RLS Rules]
-**** link:{{navprefix}}/abac-via-rls-variables[ABAC via RLS with variables]
-**** link:{{navprefix}}/jwt-abac-migration-guide[ABAC JWT migration guide]
-***** link:{{navprefix}}/jwt-filter-parameters-rules-migration-guide[JWT ABAC with filter rules -> ABAC via RLS]
-***** link:{{navprefix}}/jwt-abac-beta-migration-guide[JWT ABAC beta implementation -> ABAC via RLS]
-**** link:{{navprefix}}/abac-user-parameters[ABAC via JWT with filter rules and parameters]
-*** link:{{navprefix}}/selective-user-access[User access]
-** link:{{navprefix}}/best-practices[Performance optimization]
-*** link:{{navprefix}}/best-practices[Best practices]
-*** link:{{navprefix}}/prerender[Prerender components]
-*** link:{{navprefix}}/lazy-load-fullHeight[Full height and lazy loading options]
-*** link:{{navprefix}}/prefetch[Prefetch static resources]
-** link:{{navprefix}}/VisualEmbedSdk[Visual Embed SDK Reference]
-include::generated/typedoc/CustomSideNav.adoc[]
-*** Custom styles
-**** [.typedoc-Interface]#link:{{navprefix}}/Interface_CustomStyles[CustomStyles]#
-**** [.typedoc-Interface]#link:{{navprefix}}/Interface_CustomisationsInterface[CustomisationsInterface]#
-**** [.typedoc-Interface]#link:{{navprefix}}/Interface_customCssInterface[customCssInterface]#
-**** [.typedoc-Interface]#link:{{navprefix}}/Interface_CustomCssVariables[customCssVariables]#
-*** Runtime filters
-**** [.typedoc-Interface]#link:{{navprefix}}/Interface_RuntimeFilter[RuntimeFilter]#
-**** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_RuntimeFilterOp[RuntimeFilterOp]#
-*** Others
-**** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_Action[Action]#
-**** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_ContextMenuTriggerOptions[ContextMenuTriggerOptions]#
-**** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_DataSourceVisualMode[DataSourceVisualMode]#
-**** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_Page[Page]#
-**** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_PrefetchFeatures[PrefetchFeatures]#
-**** [.typedoc-Function]#link:{{navprefix}}/Function_executeTML[executeTML]#
-**** [.typedoc-Function]#link:{{navprefix}}/Function_exportTML[exportTML]#
-
-** Other embedding methods
-*** link:{{navprefix}}/embed-without-sdk[Embed without SDK]
-*** link:{{navprefix}}/custom-viz-rest-api[Create a custom visualization]
-** link:{{navprefix}}/troubleshoot-errors[Troubleshoot errors]
-
-* link:{{navprefix}}/rest-apis[REST API]
-** link:{{navprefix}}/rest-apis[Overview]
-** link:{{navprefix}}/api-user-management[Users and group privileges]
-** link:{{navprefix}}/rbac[Role-based access control]
-** link:{{navprefix}}/spotter-api[Spotter APIs]
-*** link:{{navprefix}}/spotter-agent-apis[AI APIs (Spotter Agent and Spotter 3)]
-*** link:{{navprefix}}/spotter-apis-classic[AI APIs (Spotter Classic) ^BETA^]
-*** link:{{navprefix}}/spotter-coaching-apis[Spotter coaching APIs ^BETA^]
+//*** link:{{navprefix}}/graphql-playground[GraphQL Playground]
-** link:{{navprefix}}/audit-logs[Audit logs]
-** link:{{navprefix}}/tml[TML]
-** link:{{navprefix}}/collections[Collections]
-** link:{{navprefix}}/connections[Connections]
-*** link:{{navprefix}}/connection-config[Connection configuration]
-** link:{{navprefix}}/rest-apiv2-getstarted[REST API v2.0]
-*** link:{{navprefix}}/rest-apiv2-getstarted[Get started]
-*** link:{{navprefix}}/api-authv2[REST API v2.0 authentication]
-*** link:{{navprefix}}/rest-apiv2-js[REST API v2.0 in JavaScript]
-*** link:{{navprefix}}/rest-apiv2-search[REST API v2.0 Search 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}}/rest-api-sdk[REST API v2.0 SDKs]
-**** link:{{navprefix}}/rest-api-sdk-typescript[TypeScript SDK]
-**** link:{{navprefix}}/rest-api-sdk-java[Java SDK]
-** link:{{navprefix}}/rest-apiv2-reference[REST API v2.0 Reference]
-** link:{{navprefix}}/rest-api-getstarted[REST API v1]
-*** 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}}/rest-api-reference[REST API v1 Reference]
-*** link:{{navprefix}}/orgs-api[Orgs API]
-*** link:{{navprefix}}/user-api[User API]
-*** link:{{navprefix}}/group-api[Group API]
-*** link:{{navprefix}}/role-api[Role API]
-*** link:{{navprefix}}/session-api[Session API]
-*** link:{{navprefix}}/connections-api[Data connection API]
-*** link:{{navprefix}}/metadata-api[Metadata API]
-*** link:{{navprefix}}/admin-api[Admin API]
-*** link:{{navprefix}}/tml-api[TML API]
-*** link:{{navprefix}}/dependent-objects-api[Dependent objects API]
-*** link:{{navprefix}}/search-data-api[Search data API]
-*** link:{{navprefix}}/liveboard-data-api[Liveboard data API]
-*** link:{{navprefix}}/liveboard-export-api[Liveboard export API]
-*** link:{{navprefix}}/security-api[Security API]
-*** link:{{navprefix}}/logs-api[Audit logs API]
-*** link:{{navprefix}}/materialization-api[Materialization API]
-*** link:{{navprefix}}/database-api[Database API]
-** link:{{navprefix}}/runtime-sort[Runtime sorting]
-** link:{{navprefix}}/v1v2-comparison[REST v1 and v2.0 comparison]
-** link:{{navprefix}}/graphql-guide[GraphQL API ^Beta^]
-** link:{{navprefix}}/webhooks[Webhooks]
-*** link:{{navprefix}}/webhooks-comm-channel[Configure and monitor webhook communication channels]
-*** link:{{navprefix}}/webhooks-s3-integration[Deliver Liveboard reports to AWS S3 Storage]
-*** link:{{navprefix}}/webhooks-lb-schedule[Deliver Liveboard reports to external application]
-*** link:{{navprefix}}/webhooks-lb-payload[Webhook response payload]
-*** link:{{navprefix}}/webhooks-kpi[Webhook for KPI alerts]
+[.sidebar-title]
+Get started
-* MCP Servers and Tools
-** link:{{navprefix}}/SpotterCode[SpotterCode for IDEs]
-*** link:{{navprefix}}/integrate-SpotterCode[Integrating SpotterCode]
-*** link:{{navprefix}}/spottercode-prompting-guide[SpotterCode prompting guide]
-** link:{{navprefix}}/ai-analytics-integration[ThoughtSpot AI analytics integration]
-*** link:{{navprefix}}/mcp-integration[ThoughtSpot MCP server]
-*** link:{{navprefix}}/connect-mcp-server-to-clients[Connecting MCP Server to MCP clients]
-*** link:{{navprefix}}/custom-chatbot-integration-mcp[Integrating MCP Server in a custom application or chatbot]
+* link:{{navprefix}}/getting-started[Embed ThoughtSpot]
+* link:{{navprefix}}/SpotterCode[SpotterCode for IDEs]
+* link:{{navprefix}}/rest-apis[REST APIs]
+* link:{{navprefix}}/ai-analytics-integration[AI analytics integration]
+* link:{{navprefix}}/mcp-integration[MCP Server integration]
+//** link:{{navprefix}}/tutorials/tutorials-overview[Tutorials]
+* link:{{navprefix}}/VisualEmbedSdk[SDK and API reference]
+** link:{{navprefix}}/VisualEmbedSdk[Visual Embed SDK]
+** link:{{navprefix}}/rest-apiv2-reference[REST API]
+** link:{{navprefix}}/mcp-tool-reference[MCP tools]
+
+
+[.sidebar-title]
+Build and deploy
+
+* link:{{navprefix}}/development-and-deployment[Development and deployment]
+** link:{{navprefix}}/thoughtspot-objects[ThoughtSpot objects]
+** link:{{navprefix}}/variables[Variables]
+** link:{{navprefix}}/parameterize-metadata[Parameterize metadata]
+
+* 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]
+
+[.sidebar-title]
+Multi-tenancy
+
+* link:{{navprefix}}/multi-tenancy[Overview]
+* 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]
+
+[.sidebar-title]
+Integration guides
+
+** link:{{navprefix}}/external-tool-script-integration[Third-party tools and custom scripts]
* link:{{navprefix}}/development-and-deployment[Deployment and integration]
** link:{{navprefix}}/development-and-deployment[Development and deployment]
*** link:{{navprefix}}/thoughtspot-objects[ThoughtSpot objects overview]
-*** link:{{navprefix}}/variables[Custom variables]
-*** link:{{navprefix}}/parameterize-metadata[Parameterize metadata]
-*** link:{{navprefix}}/git-integration[Deploy with Git]
-**** link:{{navprefix}}/git-configuration[Configure Git integration]
-**** link:{{navprefix}}/git-api[Version Control REST APIs]
-**** link:{{navprefix}}/guid-mapping[GUID mapping]
+*** link:{{navprefix}}/variables[Variables]
+*** link:{{navprefix}}/parameterze-metdata[Parameterize metadata]
*** 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[Multi-tenancy]
*** link:{{navprefix}}/orgs[Multi-tenancy with Orgs]
@@ -266,20 +108,17 @@ include::generated/typedoc/CustomSideNav.adoc[]
** link:{{navprefix}}/pendo-integration[Pendo integration with embed]
** link:{{navprefix}}/sf-integration[Integration with Salesforce]
** link:{{navprefix}}/vercel-integration[Vercel integration]
-* Additional references
-** link:{{navprefix}}/embed-ts[About ThoughtSpot embedding]
-** link:{{navprefix}}/get-started-tse[Embed licenses]
-** link:{{navprefix}}/license-feature-matrix[Feature matrix]
-** link:{{navprefix}}/faqs[FAQs]
-** link:{{navprefix}}/code-samples[Code samples]
-** link:https://codesandbox.io/s/big-tse-react-demo-i4g9xi[React CodeSandbox, window=_blank]
-** link:https://codesandbox.io/s/graphqlcookieembed-wf4fk9?file=/src/App.js:418-426[GraphQL CodeSandbox, window=_blank]
-* Resources
-** link:https://developers.thoughtspot.com[ThoughtSpot Developers, window=_blank]
-** link:https://community.thoughtspot.com/customers/s/[Community, window=_blank]
-** link:https://developers.thoughtspot.com/guides[Tutorials, window=_blank]
-** link:https://developers.thoughtspot.com/codespot[CodeSpot, window=_blank]
-** link:https://training.thoughtspot.com/page/developer[Training resources, window=_blank]
-** link:https://docs.thoughtspot.com[Product Documentation, window=_blank]
+[.sidebar-title]
+Additional resources
+
+* link:{{navprefix}}/faqs[FAQs]
+* link:https://codesandbox.io/s/big-tse-react-demo-i4g9xi[React CodeSandbox, window=_blank]
+//** link:https://codesandbox.io/s/graphqlcookieembed-wf4fk9?file=/src/App.js:418-426[GraphQL CodeSandbox, window=_blank]
+
+* link:https://community.thoughtspot.com/customers/s/[Community, window=_blank]
+* link:https://training.thoughtspot.com/page/developer[Training resources, window=_blank]
+* link:https://docs.thoughtspot.com[Product Documentation, window=_blank]
+* link:https://developers.thoughtspot.com[ThoughtSpot Developers, window=_blank]
+* Deprecated feature docs
** link:{{navprefix}}/abac-user-parameters-beta[ABAC via tokens (pre-10.4.0.cl) (Deprecated)]
diff --git a/modules/ROOT/pages/customize-homepage-full-embed.adoc b/modules/ROOT/pages/customize-homepage-full-embed.adoc
index 20f9de70e..954cb8da5 100644
--- a/modules/ROOT/pages/customize-homepage-full-embed.adoc
+++ b/modules/ROOT/pages/customize-homepage-full-embed.adoc
@@ -8,11 +8,10 @@
Developers can customize the home page experience in full application embedding to show either the classic layout or the new modular home page.
-[div announcementBlock]
---
[IMPORTANT]
+====
The classic (V1) experience and V2 experience modes will be deprecated in an upcoming release in 2026. Therefore, ThoughtSpot recommends upgrading the UI experience of your full application embedding to the V3 experience.
---
+====
== Home page layout
diff --git a/modules/ROOT/pages/deploy-with-tml-apis.adoc b/modules/ROOT/pages/deploy-with-tml-apis.adoc
index 14b0abb3a..e09eaf7d8 100644
--- a/modules/ROOT/pages/deploy-with-tml-apis.adoc
+++ b/modules/ROOT/pages/deploy-with-tml-apis.adoc
@@ -8,156 +8,258 @@
When deploying embedded analytics, each organization will have defined practices for development, testing, and deployment of content to ThoughtSpot. ThoughtSpot instances act as a constantly running service, so deployment only involves publishing *ThoughtSpot content*, in the form of link:https://docs.thoughtspot.com/cloud/latest/tml[ThoughtSpot Modeling Language (TML), window=_blank] files to a given ThoughtSpot instance.
-ThoughtSpot has xref:version_control.adoc[Git integration] designed to automate most of the steps involved in the following process. Please see if the xref:version_control.adoc[Git integration capabilities] will work for your needs before building a process with the TML APIs directly.
+The most typical pattern with ThoughtSpot involves a dev Org where content is modified by the team and then those objects are marked to form a "release" package, which then have their TML exported into a "release" branch in Git:
-NOTE: Any example workflow you see within this document has been implemented and tested within the libraries available in the xref:development-and-deployment.adoc#relatedResources[Additional Resources]. We recommend that you start with these libraries and tools.
+image::./images/multi_tenant_deployment.png[Multi-tenant Database Deployment SDLC Pattern]
+
+The TML files in the "release" branch are then moved into other "deployment branches" via pull/merge request.
+
+Other ThoughtSpot Orgs are "deployed to" by importing TML from their designated "deployment branch".
+
+The formalized release process is separate from xref:development-and-deployment.adoc#_version_control[version control], which is concerned with capturing all changes of all content in a given Org.
== Overview
The three steps to building an SDLC process with ThoughtSpot are:
- . *xref:linkExportSource[Export source]*: Downloading ThoughtSpot objects as TML files into a source control system (for example, Git)
- . *xref:linkBuildRelease[Build release]*: Altering copies of the TML files for the next stage / environment
+ . *xref:linkBuildRelease[Identify objects for release]*: Determine which objects in "dev Org" should become part of the "release" package
+ . *xref:linkExportSource[Export release TML into Git]*: Downloading ThoughtSpot objects as TML files into a source control system (for example, Git)
. *xref:linkImportRelease[Import release]*: Importing the TML files into the new environment
-Every object on a ThoughtSpot instance has a *GUID* as a unique reference.
+== Pre-requisites
+For TML files to be portable between any Org on any instance, the objects must have *obj_ids* and all Table and Connection objects must have been xref:metadata-parameterization.adoc[parameterized] with the appropriate xref:variables.adoc[variables] where necessary.
-The *most essential* aspect of steps 2 and 3 is recording any newly created object GUIDs from the destination environment into a *xref:guidMapping[mapping file]* along with the GUID of the source object.
+Once these pre-requisites are complete, your TML will be ready for TML Import across Orgs or publishing:
-When publishing to a new environment on the same ThoughtSpot instance, you *must* swap out the GUIDs from the source environment with those of the equivalent objects in the destination environment within the TML files, so that only destination environment content is referenced.
+[,YAML]
+----
+obj_id: My_Connection__DATA_CHALLENGE__SALES
+table:
+ name: SALES
+ db: ${dc_db}
+ schema: ${dc_schema}
+ db_table: SALES
+ connection:
+ name: My Connection
+ obj_id: My_Connection
+----
-== Deployment scenarios
+=== Parameterization with variables
+In a single-tenanted database pattern, customer data is split into many separate logical databases or schemas, typically with identical table structures.
-* xref:#_instance_to_instance_deployment[Instance-to-instance deployment]
-* xref:#_multiple_environments_on_the_same_instance[Multiple environments on the same instance]
+Queries for each customer can be identical by *xref:metadata-parameterization.adoc[parameterizing]* the attributes that vary. ThoughtSpot provides xref:variables.adoc[variables] that can be referenced in TML for this purpose.
-=== Instance-to-instance deployment
-The simplest deployment scenario is moving content from one ThoughtSpot instance to another separate instance.
+Details about the fully-qualified table name are stored in each Table object in ThoughtSpot, rather than in the Connection object. The following can be parameterized in a Table TML file:
-The TML Import process will use the `guid:` property of the imported TML files as the GUID for the new objects on the destination instance on all instances later than 9.0.0, which includes all ThoughtSpot Cloud deployments.
+* database
+* schema
+* db_table_name
-This means that a mapping file or swapping in and out GUIDs is not required. Make sure that all Connections have the same unique names on both instances and TML files should import without any modifications.
+Properties of a Connection can also be parameterized.
-If your instance is running a ThoughtSpot release version lower than 9.0.0.cl, refer to the xref:development-and-deployment.adoc#_notes_for_older_releases[Notes for older releases].
+Parameterization works with both TML import and xref:publishing-overview.adoc[publishing].
-=== Multiple environments on the same instance
+=== obj_id
+Before implementing any deployment process, you should ensure that `obj_id` is enabled on your ThoughtSpot instance.
-Many ThoughtSpot customers have multiple "environments" on the same instance, either using xref:orgs.adoc[Orgs] or well-defined xref:multi-tenancy-best-practices.adoc[Access Control].
+[NOTE]
+====
+Objects are only assigned automatic `obj_id` after the first change to the object once `obj_id` is enabled on an instance.
+====
-In this scenario, you must track the equivalent GUIDS between source and destination environments, and swap them out within the TML files for your deployment process to work correctly.
+`obj_id` for an object is available in the response from `/metadata/search` REST API as `metadata_obj_id` property:
-The workflow for a very simple "dev" to "prod" flow on the same environment shown here, is the same pattern for any source-to-destination environment flow:
+[,json]
+----
+{
+ "metadata_id":"c1e4043a-4524-4fcb-a20f-9e7aff4dc972",
+ "metadata_name":"Retail Sales RAD - KPIs",
+ "metadata_type":"LIVEBOARD",
+ "metadata_obj_id":"RetailSalesRAD-KPIs-c1e4043a"
+}
+----
+The format of `obj_id` above, with the `-{startOfGUID}` portion at the end, indicates it was an auto-generated obj_id. If the property value was `null`, then it is an object that has not been updated since the feature was enabled.
-image::./images/development-deployment-process.png[Development and deployment workflow]
+The `metadata/update-obj-id` REST API endpoint can change an object's `obj_id` property based on either the `metadata_id` (GUID) or the current `metadata_obj_id`:
-[#guidMapping]
-== GUID mapping file
-As noted above, keeping a *mapping file* of GUIDs of source objects and their descendant objects in the destination environment is essential. The exact structure of the file will depend on the complexity of your deployment needs.
+[,json]
+----
+{
+ "metadata": [
+ {
+ "metadata_identifier": "c1e4043a-4524-4fcb-a20f-9e7aff4dc972",
+ "new_obj_id": "RetailSalesRAD-KPIs"
+
+ }
+ ]
+}
+----
-The simplest pattern is to assume that releases are built exclusively from the "dev" environment, regardless of the destination environment. This pattern can be represented in the simple JSON structure:
+or
-[source,json]
+[,json]
----
{
- "test": {
- "" : ""
- },
- "uat": {
- "" : ""
- },
- "prod": {
- "" : ""
- }
- ...
+ "metadata": [
+ {
+
+ "current_obj_id": "RetailSalesRAD-KPIs-c1e4043a",
+ "new_obj_id": "RetailSalesRAD-KPIs"
+ }
+ ]
}
----
-You can use the same format for your mapping file as the xref:guid-mapping.adoc[Git deploy commits API] provided by ThoughtSpot. The most important aspect is recording the source GUID along with the GUID of the equivalent object in the destination after receiving the response from the `/metadata/tml/import` REST API call.
+The request format for `metadata/update-obj-id` is an array, allowing for updating a large number of objects at once.
-[#linkExportSource]
-== Export source process
-The process for exporting TML files into source control is:
+==== Implementing obj_id in existing environments
+Once you have decided on the appropriate `obj_id` for all the objects in your dev Org, you can use any existing GUID Mapping files to update the `obj_id` values for the equivalent objects in all your other Orgs.
- . Use Metadata APIs (xref:metadata-api.adoc#metadata-list[/metadata/list] in v1 or link:{{navprefix}}/restV2-playground?apiResourceId=http/api-endpoints/metadata/search-metadata[/metadata/search] in v2.0) to get a filtered list of objects
- . Use `/metadata/tml/export` endpoint in REST API v1 or v2.0 with `export_fqns=true` argument and `formmattype=YAML` to retrieve the TML of the object
- . Save the TML response strings to disk in a Git-enabled directory using a consistent name format
+You only have to do this process for existing objects *one time*, and from that point forward, you can update objects in any Org using TML with obj_ids rather than GUIDs.
-You can use the link:https://thoughtspot.github.io/cs_tools/[CS Tools, window=_blank] package for a pre-built tool for programmatic exporting or build your own equivalent using the link:https://github.com/thoughtspot/thoughtspot_rest_api_v1_python[thoughtspot_rest_api_v1 Python library, window=_blank].
+[#linkBuildRelease]
+== Identifying release package in dev Org
+The set of objects on the *dev Org* that makes up the "deployed releases" should be identified in a way that allows easy identification of the objects to be exported into Git.
-=== Best practices with TML export API
-The `formattype` argument can be set to `YAML` or `JSON`.
+The following mechanisms can be used to easily identify subsets of objects in an Org:
-Parameterization works with both TML import and xref:publishing-overview.adoc[publishing].
+* Tags
+* Content Author
+* Collections (if enabled)
-You can pass any number of GUIDs in the `export_ids` argument, although it is simpler to retrieve one at a time, particularly when processing the results obtained from the `export_associated=true` option.
+The most typical practice is to add a *Tag*, something like *release* or *rc*, to any object that should be exported into the "release" branch.
-The `export_associated` argument retrieves the TML objects for all related objects when used, including the GUID of each object within the headers. This is useful for dependency checking, and was valuable in versions lower than 8.9.0.cl to fill in `fqn` values. For more information, see xref:olderReleaseNotes[Notes for older releases].
+You can add multiple tags, if you'd like to add tags indicating versioning along with the release indicator.
-[#linkBuildRelease]
-== Build release process
-To change the source environment TML files so that they can be imported into the destination environment, you need a process that correctly manipulates the TML files.
+The `/metadata/search` REST API endpoint has parameters to filter on `tag_identifiers` and `created_by_user_identifiers`. The response from `/metadata/search` can be processed further to reduce down to the desired list of object IDs to pass to the `/metadata/tml/export` endpoint.
-Common adjustments include:
+[,json]
+----
+{
+ "metadata": [
+ {
+ "type": "LIVEBOARD"
+ }
+ ],
+ "tag_identifiers": ["release"],
+ "sort_options": {
+ "field_name": order_field,
+ "order": "DESC"
+ },
+ "record_size" : -1,
+ "record_offset": 0
+}
+----
-* Switching connections at the Table level
-* Changing database details within Table objects
-* Adding or removing columns
-* Renaming columns for translations
+The `author` property of an object in the REST API is the value that the `created_by_user_identifiers` parameter in the `/metadata/search` endpoint filters on. `author` can be reassigned from the original creator via the link:https://developers.thoughtspot.com/docs/restV2-playground?apiResourceId=http%2Fapi-endpoints%2Fsecurity%2Fassign-change-author[/security/metadata/assign, window=_blank] endpoint.
-For information about the specific TML changes to achieve these goals, see xref:modify-tml.adoc[Modify TML files]. There are also functioning code examples of many of these changes in the link:https://github.com/thoughtspot/thoughtspot_tml[thoughtspot_tml, window=_blank] repository.
+[#linkExportSource]
+== TML Export with obj_id and variables
+The process for exporting TML files into source control is:
-=== GUIDs in TML files determine create vs update operations
+ . Use Metadata Search REST API link:{{navprefix}}/restV2-playground?apiResourceId=http/api-endpoints/metadata/search-metadata[/metadata/search] to get a filtered list of objects for the release
+ . Use `/metadata/tml/export` endpoint with `formattype=YAML` to retrieve the TML of the object
+ . Save the TML response strings to disk in a Git-enabled directory using a consistent name format based on the `obj_id`
-Objects of the same or different types can have the same display name in ThoughtSpot, so the GUID is necessary to identify the particular object.
-In the REST APIs, `id` properties are the GUIDs.
+=== Best practices with TML export API
+The `/metadata/tml/export` endpoint has many options for controlling the format of the response.
-In TML:
+==== YAML or JSON
+The `formattype` argument can be set to `YAML` or `JSON`.
-* the `guid:` property will be at the top of the file
-* `fqn:` properties are used to reference other connected objects (typically data sources) with a GUID
+Export in YAML for saving to disk for use in Git or when using the `thoughtspot_tml` library, which is designed to handle the TML YAML format.
-==== Rules for create vs. update operations
-Object names are *never used* for determining an object to update, because object names are not unique within ThoughtSpot.
+Export in JSON when you need details from TML within a web browser or just need to read values programmatically.
-Whether an imported TML will create a new object or update an existing object depends on:
+==== obj_id or guid
+Once all your objects have defined `obj_id` properties, the ideal TML Export setting has the following options (you may have more or others as well):
-* the presence/absence of the *guid:* property in the TML file
-* whether that GUID matches an existing object on that ThoughtSpot instance
-* the `force_create=true` parameter
+[,json]
+----
+{
+ "edoc_format": "YAML",
+ "export_associated": false,
+ "export_fqn": false,
+ "export_options": {
+ "include_obj_id": true,
+ "include_obj_id_ref": true,
+ "include_guid": false
+ }
+}
+----
-Creation vs. update is determined by the following rules:
+`"include_obj_id": true` specifies the `obj_id` at the top of the YAML file as the identifier for the object.
- - *No GUID* in the TML file: always creates a new object with a new GUID
- - *GUID in TML file*, where an object with the *same GUID already exists* in instance: update object
- - *GUID in TML file*, where *no object with same GUID exists* in ThoughtSpot instance: creates a new object with the GUID from the TML file
- - *Table objects* match on fully-qualified tables in the database (each Connection can only have one Table object per table in the database), not GUID: If a Table object representing the same database table is found, the GUID of the original object is maintained, but the updates are applied from the new TML file
- - *force_create=true* parameter of the TML Import API is used: every uploaded TML file results in new objects being created
+`"include_obj_id_ref": true` specifies that any related objects referenced in the TML file have an `obj_id` property as well.
-[NOTE]
-====
-In versions prior to 9.0.0.cl, ThoughtSpot did not consistently use the GUID provided in the TML file for a new object when that GUID was not already in use on that ThoughtSpot instance.
-====
+The TML will end up looking like:
-=== GUID mapping and swapping
-Regardless of the other changes you make, building a release for an environment on the same instance will require swapping in the correct GUIDs. Because the presence of the *guid* property determines whether an individual TML file will cause a create or update action, you need to keep a *GUID mapping file* to determine how to adjust the TML files for upload to the new environment.
+[,YAML]
+----
+obj_id: My_Connection__DATA_CHALLENGE__SALES
+table:
+ name: SALES
+ db: ${dc_db}
+ schema: ${dc_schema}
+ db_table: SALES
+ connection:
+ name: My Connection
+ obj_id: My_Connection
+----
+
+If any of the objects do not have `obj_id` set, the TML will be exported with the `guid` property at the top, or the `fqn:` property for a reference, which will be the referenced object's GUID:
+
+[,YAML]
+----
+guid: c1e4043a-4524-4fcb-a20f-9e7aff4dc972
+table:
+ name: SALES
+ db: ${dc_db}
+ schema: ${dc_schema}
+ db_table: SALES
+ connection:
+ name: My Connection
+ fqn: 75b717da-94b6-42ae-ab93-110c677703fb
+----
+
+
+==== export_associated
+The `export_associated` argument retrieves the TML objects for all related objects when used, including the GUID of each object within the headers. This is useful for dependency checking, but results in longer request times and bigger responses, and possibly exporting the same object over and over.
-The *guid mapping file* is referenced when creating the final TML files for publishing and then should be updated with any new object GUIDs after publishing:
+=== File and directory naming pattern
+`obj_id` must be unique within an Org, which makes it the obvious value to use as part of the filename of the YAML file on disk. ThoughtSpot's default file name pattern also includes the object type in the filename, resulting in a suggested pattern:
- . Check the *guid mapping file*
- .. If no key-value pair exists for the *dev GUID* for the new environment: *remove the guid property from the TML file*. This will cause a *create* action
- .. If a key-value pair exists: *swap* the TML file *guid* value from the *dev GUID* to the *destination environment GUID*. This will cause an *update* action
- . When a new object is published for the first time, record the *dev GUID* as the key, and the *new object GUID* as the value
- . Perform the same process for any *fqn* properties, which specify data object references. Remove the *fqn* property if the data object is being newly created, or swap it to the mapped GUID for that environment
+`{obj_id}.{object_type}.tml`
-The link:https://github.com/thoughtspot/thoughtspot_tml[thoughtspot_tml library, window=_blank] provides a helper function called `disambiguate()` which implements the logic described above when provided with a Dict representing the GUID map. For information about how to use the library, see the README and examples or look at the source code if building an equivalent process yourself in another language.
+You may also want to store various object types in their own directories on disk for ease of organization.
+
+The `obj_id` should be the first line of any TML file, and the object type should be the second, so you can easily build the filename from the `edoc` response from the TML Export REST API like:
+
+[,python]
+----
+if 'edoc' in yaml_tml[0]:
+ lines = yaml_tml[0]['edoc'].splitlines()
+
+ if lines[0].find('obj_id: ') != -1:
+ obj_id = lines[0].replace('obj_id: ', "")
+ else:
+ # Exception path of your choice
+
+ obj_type = lines[1].replace(":", "")
+
+ # Save the file with {obj_type}s/{obj_id}.{type}.{tml}
+ # Feel free to change directory naming structure to not have 's' at end
+ directory = "{}s".format(obj_type)
+ filename = "{}/{}.{}.tml".format(directory, obj_id, obj_type)
+----
[#linkImportRelease]
-== Import release process
-The xref:tml-api#import[/metadata/tml/import] REST API endpoint is used to upload any number of TML files at one time.
+== 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.
-All details of the objects to be created or modified are specified *within the uploaded TML file*, including the GUID which determines which existing object a given TML file will update.
+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.
-The xref:development-and-deployment#linkBuildRelease[Build release process] section above describes the process for getting the TML files prepared for the import release process. The following describes the Import TML REST API call and what to do with the responses, which do feed back into the build release process in the form of the *GUID mapping file*.
+If no match is found for `obj_id` or `guid`, a new object is created, with the `obj_id` specified in the TML file (`guid` will be auto-assigned).
=== TML import options and responses
@@ -167,146 +269,52 @@ ThoughtSpot does not consider object display name for a TML file, but does use n
All data objects are referenced as "tables" within TML, whether they are a ThoughtSpot Table, Model, View, SQL view, or any other data object type.
The following heuristic is used to find matching objects by name within `tables` or `joins` sections:
-
+
+ . `obj_id` within other files in the same TML Import operation or existing objects in the Org
. Data object names within the same TML Import operation: Must only be one single object with that name
- . Searches the entire ThoughtSpot instance: Must be only one single object with that name
+ . Searches the entire ThoughtSpot Org: Must be only one single object with that name
-The best practice is to create and upload "packages" of related objects together at once:
+For this reason, we recommend importing Tables and Models from the same Connection in the same Import TML request, at least on the initial import.
-* Give data objects within a package unique names, even though not enforced by ThoughtSpot
-* All Table objects that use the same Connection object and all Models connected to those Tables should be uploaded together in a single TML Import
-* If a data object already exists, swap out the *fqn* references to avoid the name matching heuristic
+==== Rules for create vs. update operations
+Object names are *never used* for determining an object to update, because object names are not unique within ThoughtSpot.
-==== Storing new GUIDs in a mapping
-To track relationships between objects in different environments, particularly on the same instance, you must store a *mapping* of the child object GUID to its source object GUID when you first publish the child object.
+Whether an imported TML will create a new object or update an existing object depends on:
-The xref:tml-api#import[import REST API endpoint] returns the GUID in the response after a successful import. The `object` key of the response to the import call contains an array, where each element has a `["response"]["header"]["id_guid"]` key providing the GUID. If you import multiple TML files at once, the response array will be in the same order as the request. This allows you to record a mapping of the originating GUID to the newly created GUIDs.
+* the presence/absence of the *obj_id:* property in the TML file
+* the presence/absence of the *guid:* property in the TML file
+* whether that GUID matches an existing object on that ThoughtSpot instance
+* the `force_create=true` parameter
-[source,json]
-----
-{
- "object": [
- {
- "response": {
- "status": {
- "status_code": "OK"
- },
- "header": {
- "id_guid": "a09a3787-e546-42cb-888f-c17260dd1229",
- "name": "Basic Answer 1",
- "description": "This is basic answer with table and headline visualizations.",
- "author_guid": "59481331-ee53-42be-a548-bd87be6ddd4a",
- "owner_guid": "a09a3787-e546-42cb-888f-c17260dd1229",
- "metadata_type": "QUESTION_ANSWER_BOOK"
- }
- }
- }
- ]
-}
-----
+Creation vs. update is determined by the following rules:
-Update the *mapping file* with the new pair of source object GUID and destination environment object GUID, so that the release build process can do the appropriate swaps the next time the object needs to be updated.
+*obj_id* is always considered first if present. ThoughtSpot looks at org_id + obj_id to find any existing object in that Org with a match, then creates a new object if one is not found
+If only GUIDs are in the TML file, without obj_id, the rules are:
-[#relatedResources]
-== Additional Resources
+ - *No GUID* in the TML file: always creates a new object with a new GUID
+ - *GUID in TML file*, where an object with the *same GUID already exists* in instance: update object
+ - *GUID in TML file*, where *no object with same GUID exists* in ThoughtSpot instance: creates a new object with the GUID from the TML file
+ - *force_create=true* parameter of the TML Import API is used: every uploaded TML file results in new objects being created
-* The link:https://github.com/thoughtspot/thoughtspot_tml[thoughtspot-tml module, window=_blank] is written in Python providing classes to work with the TML files as Python objects. You can install it via pip:
+Table objects match on the real existence of the table in the particular database:
-+
-----
-pip install thoughtspot_tml
-----
+ - *Table objects* match on fully-qualified tables in the database (each Connection can only have one Table object per table in the database), not GUID or obj_id: If a Table object representing the same database table is found, the obj_id/GUID of the original object is maintained, but the updates are applied from the new TML file
-* The link:https://github.com/thoughtspot/thoughtspot_rest_api_v1_python[thoughtspot-rest-api-v1 module, window=_blank] is a Python module implementing the full ThoughtSpot V1 REST API. You can install it via pip:
-+
-----
-pip install thoughtspot_rest_api_v1
-----
+[#relatedResources]
+== Additional Resources
-* The link:https://github.com/thoughtspot/ts_rest_api_and_tml_tools[ts_rest_api_and_tml_tools project, window=_blank] provides examples of workflows using the REST API and TML modification possible with the `thoughtspot_tml` and `thoughtspot_rest_api_v1` modules. This library is intended to provide working examples and is not maintained or supported by ThoughtSpot.
+* The link:https://github.com/thoughtspot/thoughtspot_tml[thoughtspot_tml library, window=_blank] is written in Python providing classes to work with the TML files as Python objects. You can install it via pip:
-* The link:https://github.com/thoughtspot/ts_rest_api_and_tml_tools/blob/main/examples/tml_and_sdlc/[examples/tml_and_sdlc/, window=_blank] directory includes many different example scripts for these TML-based workflows.
+
-////
-Within the examples directory, the link:https://github.com/thoughtspot/ts_rest_api_and_tml_tools/blob/main/examples/tml_and_sdlc/tml_download.py[tml_download.py, window=_blank] script is a simple example of exporting all TML objects to disk for use with Git or another source control system.
-////
-* For command-line administration tools including many pre-built TML-based workflows, the link:https://github.com/thoughtspot/cs_tools[cs_tools project, window=_blank] is available.
-
-////
-== Notes for older releases (8.9.0.cl or earlier versions)
-
-[#olderReleaseNotes]
-=== Add FQNs of associated objects in TML
-Prior to ThoughtSpot 8.9.0.cl, TML files did not include the GUIDs of associated objects on export. However, you can use the `export_associated=true` argument to retrieve the GUIDs of the associated objects, then programmatically add the `fqn` property to the downloaded TML with the correct GUIDs. Including the GUIDs in the saved files on disk allows you to substitute the GUIDs for the equivalent objects in another environment.
-
-For example, in these earlier versions, the items in the `tables:` list of this example worksheet TML only include a `name:` property, representing the name of the ThoughtSpot *table* object (as opposed to the table's name in the data warehouse).
-
-If there are *table* objects with duplicate names, specify the GUID of the object using the `fqn:` property. This will distinguish the correct object when importing the TML back.
-
-When you set `export_associated=true` in the TML export command, the first item in the response will be the object you requested in the export:
-
-[source,yaml]
----
-guid: 0a0bb654-b0e8-482c-a6c8-9ed396d1cb92
-worksheet:
- name: Markspot 2 Worksheet
- tables:
- - name: DIM_CUSTOMERS_2
- table_paths:
- - id: DIM_CUSTOMERS_2_1
- table: DIM_CUSTOMERS_2
- join_path:
- - {}
-...
-----
-
-The overall response will be structured as a JSON array, with an `edoc` property representing the TML document itself and an `info` section providing basic metadata information, but more importantly the `name` and `id` properties.
-
-[source,json]
-----
-{
- "object": [
- {
- "edoc": ""
- ,
- "info": {
- "id": "