ThoughtSpot Modeling Language
ThoughtSpot Modeling Language (TML) is a markup language that represents ThoughtSpot objects (Models, Answers, Liveboards, tables, etc.) as human-readable text files, enabling version control, bulk editing, and migration of ThoughtSpot content.
TML files use YAML syntax and map one-to-one with ThoughtSpot objects. You can download, edit, and re-upload them to update content, migrate between instances, or manage objects programmatically.
To work with TML files, download a ThoughtSpot object (Model, view, SQL view, table, Answer, Liveboard, or Monitor alert) to a flat file in .TML format. Modify the file, and then upload it to the same instance or to a different instance.
To learn how to export, change, and update Models, views, tables, Answers, and Liveboards, see Import and export TML files. To learn how to migrate multiple TML files at a time, see Migrate multiple TML files.
Each article below describes the TML syntax for a specific object type, including how to add and modify joins for Models, views, SQL views, and tables.
See the following articles for the full syntax of each type of TML file:
Object ID in TML files
Object ID (obj_id) is a user-defined, human-readable identifier that you can assign to supported ThoughtSpot objects, in addition to the system-generated GUID. A GUID is different in every Org and instance, but an obj_id stays the same when you rename an object, export and import its TML, or move it between Orgs and instances. This makes obj_id the recommended identifier for CI/CD pipelines and multi-Org deployments.
For the REST API endpoints that work with obj_id, see Object ID (obj_id) in the ThoughtSpot developer documentation.
Object ID is optional
Object ID is optional. Existing workflows that rely on GUIDs or FQNs continue to work without changes, and an Org can contain a mix of objects with and without an obj_id. You can adopt obj_id incrementally, starting with only the objects you promote across environments.
To disable Object ID, contact ThoughtSpot Support.
Supported object types
The following object types support obj_id:
| Object type | In TML |
|---|---|
Liveboard |
|
Answer |
|
Model |
|
Table |
|
SQL view |
|
Column |
No TML file of its own. Defined inside table and Model TML. |
Connection |
|
Collection |
|
Custom action |
No TML file of its own. Supported for custom actions managed through the API or the server. |
Personalized view |
No TML file of its own. Defined inside Liveboard TML, where each view carries its own |
Variable |
No TML file of its own. Supported from 26.10.0.cl. Template variables can also reference Object IDs from 26.10.0.cl. |
Memory |
No TML file of its own. Carries the Object ID of the Model it is tagged to. |
Group |
No TML file of its own. |
Role |
No TML file of its own. |
|
The |
Objects that do not support Object ID
The following objects do not have an obj_id:
| Object | Behavior |
|---|---|
Visualization on a Liveboard |
In TML, a visualization is identified only by |
Liveboard tab |
A tab is identified only by its |
Monitor alert |
The alert has no |
Schedule |
Liveboard schedules reference visualizations through |
Webhook |
The |
Parameter |
Parameters have no |
Semantic integration |
Semantic integrations have no |
User |
Users are identified by name in TML, so they migrate without an |
Tag |
Tags are identified by name in TML, so they migrate without an |
Org |
The Org is part of the uniqueness key for an |
How object identity resolves
When you import a TML file, ThoughtSpot matches it to an existing object in the target Org in the following order:
-
Object ID (
obj_id) -
GUID (
guid) -
Name / FQN
If none of these match, ThoughtSpot creates a new object.
When the obj_id in the TML matches an object in the target Org, ThoughtSpot updates that object and does not use the guid for resolution. Any GUID mapping in your deployment process has no effect on that object.
If the obj_id does not match any object in the target Org, ThoughtSpot falls back to the guid in the TML and updates the object with that GUID. The import returns a WARNING status. It does not fail or create a duplicate object.
|
Avoid TML files where the |
Uniqueness and scope
An obj_id must be unique per object type within an Org.
-
An Answer and a Liveboard in the same Org can share the same
obj_idvalue because they are different object types. -
Two Answers in the same Org cannot share the same
obj_id. -
The same
obj_idcan exist independently in multiple Orgs. This is the key behavior that enables cross-Org migration: you can userevenue-dashboardas anobj_idin your Dev, Staging, and Production Orgs simultaneously, and each Org maintains its own object with its own GUID.
Naming rules
An obj_id value must follow these rules:
-
It must be 1 to 64 characters long.
-
It can contain letters (
a-z,A-Z), numbers (0-9), hyphens (-), underscores (_), periods (.), and tildes (~). -
It cannot contain spaces or other special characters, such as
/,@,#,$,&,*, or!.
Do not use a value that has the same format as a GUID. When ThoughtSpot resolves an identifier in a URL, it tries a GUID-shaped value as a GUID first, so a GUID-shaped obj_id might not resolve as expected.
Recommended naming pattern:
Treat obj_id values like URL slugs. Keep them lowercase, concise, and descriptive. For example:
-
revenue-by-region -
prod.sales.model -
quarterly-pipeline-lb
Using a consistent naming convention across your Orgs makes TML files easier to read and reduces errors during migration.
Auto-generated values
ThoughtSpot assigns an obj_id automatically:
-
ThoughtSpot assigns an
obj_idto each object when it is created. -
Objects that existed before Object ID was enabled do not receive an
obj_idretroactively. They receive one the first time they are updated or imported through TML.
An automatically generated obj_id combines the object name with the first segment of the object’s GUID. For example, a Liveboard named Retail Sales RAD - KPIs might receive the obj_id RetailSalesRAD-KPIs-c1e4043a.
Because the generated value includes part of a GUID, copies of the same object in different Orgs receive different generated values. For any object that you deploy across Orgs, replace the generated value with a deliberate identifier and use the same value in every Org. To override the value, use the TML editor or edit the TML file directly.
Setting or changing an object ID
You can set or change an obj_id using the TML editor in the ThoughtSpot UI:
-
Navigate to the object, click the More menu, and scroll to the TML section.
-
Select Edit.
-
When the TML file opens, click Edit and select Change ObjectId.
-
In the text box, enter a unique string to identify the object. Click Change.
The top of the TML file now shows both identifiers:
guid: <system_generated_guid> obj_id: <your_unique_string>
You can also set the obj_id by editing it at the top of a TML file and importing the file.
Before you change an existing obj_id, export the object’s TML as a backup. After the change, the previous value no longer resolves. Update all references: TML files that use the obj_id, TML file names in your Git repository, and deployment scripts.
To change the obj_id of many objects at once, use the REST API. For more information, see Object ID (obj_id).
Object IDs of referenced objects
TML can identify the objects it references by obj_id as well. For example, a table’s TML can reference its connection by obj_id:
obj_id: My_Connection__RETAIL__SALES
table:
name: SALES
db: RETAIL
schema: PUBLIC
connection:
name: My Connection
obj_id: My_Connection
Monitor alert TML references its Liveboard or Answer through pinboard_obj_id or answer_obj_id. See Objects that do not support Object ID.
Exporting TML with object IDs
When Object ID is enabled, TML that you export from the ThoughtSpot UI includes the obj_id automatically.
TML exported through the REST API does not include obj_id by default. For the export options that include the obj_id of the object and of its referenced objects, see TML export.
Importing TML with object IDs
When you import a TML file that contains an obj_id:
-
If the
obj_idmatches an existing object in the target Org, ThoughtSpot updates that object. -
If no object matches the
obj_id, ThoughtSpot falls back to the GUID and then the name, as described in How object identity resolves. -
If nothing matches, ThoughtSpot creates a new object and assigns it the
obj_idfrom the TML.
Because obj_id is consistent across Orgs, you do not need to remap GUIDs when migrating content between environments.
Personalized views: Liveboard TML includes an obj_id for each personalized view. When you import Liveboard TML through the TML import API, you can opt in to update existing personalized views by obj_id instead of overwriting them. Import from the UI uses the original merge behavior. For more information, see TML import.
Clone behavior
When you clone an object that has an obj_id, the clone receives a new, distinct obj_id. The original object’s obj_id is not copied to the clone, ensuring uniqueness within the Org.
Git integration
Object ID values are part of the TML content, so they are preserved when you commit TML files to Git and import them again.
The Git commit APIs used for Git version control do not use obj_id. For Object ID-based deployments, import TML files from your repository through TML import. For an example Git workflow that names TML files after their obj_id, see Git provider integration.
Moving content between Orgs with object IDs
Without obj_id, moving TML between Orgs or instances requires you to track the GUID of each copy of an object, because the same object gets a different system-generated GUID in each Org. With obj_id, the same identifier resolves to the correct object in every Org:
| Environment | obj_id |
GUID (system-generated) |
|---|---|---|
Dev |
|
|
Staging |
|
|
Production |
|
|
When you move content between Orgs using TML, keep the following in mind:
-
Use the same
obj_idfor every copy of an object. Assign the value in each Org where a copy exists, following a consistent naming convention. Do not rely on automatically generated values, because they include part of the GUID and differ between Orgs. -
The first import creates the object. If no object in the target Org matches the
obj_id, GUID, or name in the TML, ThoughtSpot creates the object and assigns it a new GUID in that Org. To make sure ThoughtSpot creates a new object, remove theguidfrom the TML before the first import. -
Later imports update the object. When you import the same TML again, ThoughtSpot finds the existing object by its
obj_idand updates it. -
You can adopt Object ID gradually. Start with the objects you move most often. GUID-based and FQN-based workflows continue to work for the rest.
Visualizations and Liveboard tabs do not have an obj_id. Objects that point to a visualization, such as Monitor alerts, Liveboard schedules, and related links, still depend on a GUID that is different in each Org. See Objects that do not support Object ID.
|
To automate these steps in a CI/CD pipeline with the REST API and Git, see Adopting obj_id in a deployment pipeline.
For other ways to move content between Orgs and environments, see:
-
Publishing objects between Orgs: Publish objects from the Primary Org to other Orgs without creating a separate copy in each Org.
-
Migrate multiple TML files: Export and import several objects at once from the ThoughtSpot UI.
-
Create variables: Use different tables or connection properties in each Org with the same TML.
Quick reference
| Topic | Summary |
|---|---|
Is it required? |
No. Object ID is optional. Existing GUID and FQN workflows are not affected. |
Supported objects |
Liveboards, Answers, Models, tables, SQL views, columns, connections, Collections, custom actions, personalized views, variables, memory, groups, and Roles. Visualizations, Liveboard tabs, Monitor alerts, schedules, webhooks, and parameters do not have an |
Resolution order |
Object ID → GUID → Name/FQN. The |
Uniqueness |
Unique per object type, per Org. The same |
Format |
1 to 64 characters: letters, numbers, hyphens, underscores, periods, and tildes. No spaces or other special characters. |
Auto-generated? |
Yes. New objects receive one on creation; existing objects receive one on their first update or TML import. Override it for objects that you move between Orgs. |
Export (UI) |
Included automatically when Object ID is enabled. |
Import behavior |
Matches by |
Changing an |
The previous value stops resolving. Update all references to it. |
Clones |
Clones receive a new, distinct |
Git |
|
Disabling |
Contact ThoughtSpot Support to disable the feature. |
fqn
The fqn parameter refers to the source table’s GUID. You can find this string of letters and numbers at the end of the URL for that table or connection.
For example, in https://<company>.thoughtspot.com/#/data/tables/34226aaa-4bcf-4d6b-9045-24cb1e9437cb, the GUID is 34226aaa-4bcf-4d6b-9045-24cb1e9437cb.
Use this optional parameter to reduce ambiguity and identify a specific table, if you have multiple tables with the same name. When exporting a TML file, select Export FQNs of referenced objects to include FQNs for the underlying tables and connections. If you do not add the fqn parameter, and the connection or table you reference does not have a unique name, the file import fails.
Limitations of working with TML files
The following limitations apply when you edit a Model, Answer, table, view, Liveboard, or Monitor alert through TML.
-
Formulas and columns can either have a new name, or a new expression. You can’t change both, unless migrating or updating the Model two times.
-
It isn’t possible to reverse the join direction in the TML script.
-
You can only change logical tables using TML files. You can’t change the physical version of the table that exists in a database. When you change the
column_name, for example, the name changes in the application, but not in the physical table in the database. -
You can’t create or export TML files for R- or Python-powered visualizations.
-
Joins only appear in the table TML file of the source table in a join, or the table on the Many side of a Many-to-One join. You can only add and edit table joins from the TML file of the table on the Many side of the join. You can’t view or modify table-level joins from the destination table’s TML file.
-
You can’t modify joins at the table level from the Model, view, or Answer TML file. You can only override the joins for that specific Model, view, or Answer. To modify table-level joins, you must edit the source table’s TML file.
-
You can’t remove tables from a connection. You can only add them.
-
You can only delete table columns that have no dependents. If the table column has any dependents, ThoughtSpot returns an error when you try to import or validate the TML file. To delete a table column, you must first delete the dependents.
-
When deleting columns, you only delete ThoughtSpot’s record of the column. You don’t delete the column in your external database.
-
If there is an error in any row-level security (RLS) rule when importing a table, all RLS rules for the table are removed. ThoughtSpot warns you about this on import, and highlights the rule that is in an error state, so you can fix it or remove it.
-
Changing the filter order for Answers in the UI doesn’t change the filter order in the TML file.
-
Import of TML does not support Models that have the same name for parameters as for column names. This will result in a timeout during the TML validation process.
-
When a user sets a table visualization column header to blank (custom_name: "") and then exports/re-imports the Liveboard via TML, the blank header is not retained and uses the original column name instead.