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: [email protected]
TML
ThoughtSpot Modeling Language (TML) is a scriptable format developed by ThoughtSpot for exporting, modifying, and migrating metadata objects such as Models, Views, Tables, Liveboards, and Answers. TML files allow you to manage and version control these objects outside the ThoughtSpot UI, supporting workflows like bulk changes, migration between environments, and programmatic edits via REST API. Users can use TML to model data and build analytics content in the test environment in a flat-file format, and then import and deploy it in their environments.
Structure of a TML fileπ
To work with TML files for Models, views, SQL views, tables, Answers, Liveboards, and Monitor alerts in ThoughtSpot, you can download these objects as a flat file in .TML format, modify, and subsequently upload the TMLs either to the same or a different cluster.
The TML syntax varies per object type. However, all TMLs follow a general pattern that allows programmatic edits. ThoughtSpot offers a lot of flexibility within its set of data objects, and there is no particular hierarchy to TML files, but rather just some rules.
See the following pages for the detailed syntax of TML files for each object type:
For TML modification tips and recommendations, see TML modification.
TML import and export via REST APIπ
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 |
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)
-
POST /tspublic/v1/metadata/tml/import (REST API v1)
|
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 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
authorfield 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_idfield provides stable cross-environment object identity for inter-Org deployments. Use the sameobj_idvalue across environments to ensure consistent identity during migrations.
Example for a Personalized View TML with Object IDπ
Limitation without this feature enabledπ
ThoughtSpotβs 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 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π
| Policy | Behavior | Recommended use case | Limits and risks |
|---|---|---|---|
| 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. |
| 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. |
| 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. |
| 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 |
|
Important
|
Use |
Size your import tasksπ
-
For
ALL_OR_NONEandVALIDATE_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
PARTIALandPARTIAL_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.
| Status value | Description |
|---|---|
| The task is waiting to be processed.
The queue limit is 100 concurrent tasks.
Tasks submitted beyond the limit are rejected immediately with status |
| The task is being processed. |
| The task processing is complete.
|
| 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: trueonly 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: trueonly 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
trueif 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
trueto 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:
| Form parameter | Description | Default |
|---|---|---|
| Array of strings. Array of the TML strings. | None |
| Boolean. To create TML objects with new GUIDs during import, specify |
|
| 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. |
|
| String. Policy to follow during import. The allowed values are:
|
|
| Boolean |
|
| Boolean |
|
| Boolean |
|
Example requestπ
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:
{
"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
| 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:
| Form parameter | Description | Default | ||
|---|---|---|---|---|
| Array of strings. Task IDs assigned to the scheduled TML async import operations. | None | ||
| Array of strings. Status of the scheduled import tasks to filter on. The following options are available: * | None | ||
| String. GUID of the author who initiated the import request. | None | ||
| Boolean. Specify whether to include import response in the task status objects. |
| ||
| Integer. The offset point, starting from where the task status should be included in the response. |
| ||
| Integer. The number of task statuses to include in the response starting from offset position.
|
|
|
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π
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.
{
"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
| 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:
-
POST /api/rest/2.0/metadata/tml/export (REST API v2)
-
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:
-
POST /api/rest/2.0/metadata/tml/export/batch (REST API v2)
-
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 totrue, exports the associated objects for theexport_idsspecified 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 Models, 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 totrue, 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 totrue, 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 totrue, 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 totrue, 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_rulesBeta
When set totrue, exports the column-level security rules defined on the object. Contact ThoughtSpot Support to enable the feature. -
export_with_column_aliasesBeta
When set totrue, export column aliases of the Model if the data Model includes any column aliases.
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 Export a TML object using REST API v1.
TML modificationπ
ThoughtSpot offers a lot of flexibility within its set of data objects, and there is no particular hierarchy to TML files, but rather just some rules. Visit this page for detailed information on TML modification.