TML API

TML API

The TML API endpoints allow you to programmatically export, validate, and import scriptable ThoughtSpot Modeling Language (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

Starting with version 8.9.0.cl, ThoughtSpot exports TML files with liveboard as the object name instead of pinboard. Older TML files with the pinboard object name can still be imported into ThoughtSpot instances on 8.9.0.cl release version, but it will be replaced with liveboard during TML export. Importing a TML file generated from ThoughtSpot 8.9.0.cl into 8.8.0.cl or earlier versions is not supported if the object name is set to liveboard. To resolve this issue, replace liveboard with pinboard and then try to import it into earlier versions.

Supported operationsšŸ”—

API endpointAvailable from

POST /tspublic/v1/metadata/tml/import
Imports object representations in the ThoughtSpot Modeling Language (TML) format.

ThoughtSpot Cloud ts7.may.cl
ThoughtSpot Software 7.1.1

POST /tspublic/v1/metadata/tml/export
Exports objects from ThoughtSpot as TML representations.

ThoughtSpot Cloud ts7.may.cl
ThoughtSpot Software 7.1.1

Required permissionsšŸ”—

You must have at least view access to the objects to export the TML data. To import a modified TML object, your account must have the DATAMANAGEMENT privilege.

Import TMLšŸ”—

To import TML representation of objects into ThoughtSpot, use the /tspublic/v1/metadata/tml/import API endpoint.

The import TML API endpoint allows you to upload multiple TML files at a time. If you are importing TML files one at a time, include the fqn property to distinguish objects that have the same name. For example, if you have multiple connections or tables with the same name, the connection or table you reference in your TML does not have a unique name and thus 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.

Note

You can import single or multiple objects using the tml/import API. If you import only a Worksheet object, it may take some time for the Worksheet 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 Worksheet along with Liveboards, answers, and other dependent objects in a single API call, the imported objects will be immediately available for use.

Resource URLšŸ”—

POST /tspublic/v1/metadata/tml/import

Request parametersšŸ”—

Form parameterDescriptionDefault

import_objects

String. An x-www-form-urlencoded string containing a JSON array of TML objects to upload, in YAML or JSON format.

If in YAML format within the JSON array, use escape characters for YAML quotes, and new line characters when there is a new line.

For example:

  • To import a single object, ["guid: 3729c085-8659-48fd-9479-a67bd7307496\npinboard:\n name: ā€¦"]

  • To import multiple objects, ["guid: 3729c085-8659-48fd-9479-a67bd7307496\npinboard:\n name: ā€¦ā€œ, "guid: 5739d025-8659-48fd-9479-a67bd7704212\npinboard:\n name: ā€¦ā€]

None

import_policy

String. Policy to follow during import. The allowed values are:

  • PARTIAL Imports all objects that validate successfully, and ignores objects that do not validate successfully.

  • ALL_OR_NONE Imports the objects that validate successfully.

  • VALIDATE_ONLY Validates the objects but does not import them.

PARTIAL

force_create

Boolean. Specifies if you are updating or creating objects. To create new objects, specify true.

By default, ThoughtSpot updates existing objects that have the same GUID as the objects you are importing. When set to true, the guid property in the imported TML is replaced with a new GUID if the GUID is being used by another object on the server.
If the imported TML file includes a guid that is not used by any other object, ThoughtSpot creates a new object with the same guid from the imported TML file.
To know GUID assigned to the new object created from TML import, check the id_guid property in the response headers.

false

Example requestšŸ”—

Make sure the API request has the following headers:

  • The Accept header is set as Accept: text/plain

  • The X-requested-by header set as X-Requested-By: ThoughtSpot

cURL
curl -X POST --header 'Accept: text/plain' --header 'X-Requested-By: ThoughtSpot' --data-urlencode 'import_objects=[{
	"guid": "12289fad-f230-485e-8c65-e36082eebf44",
	"answer": {
		"name": "Basic Answer 1",
		"description": "This is basic answer with table and headline visualizations.",
		"tables": [{
			"id": "LINEORDER",
			"name": "LINEORDER",
			"fqn": "2445fe81-30d6-46fa-9f42-f6b1b4e01623"
		}, {
			"id": "PART",
			"name": "PART",
			"fqn": "a7fc012e-bdb3-4e75-9ce4-b3f731d90136"
		}],
		"search_query": "[LINEORDER_1::Revenue] [PART_1::Color]",
		"answer_columns": [{
			"name": "Total Revenue"
		}, {
			"name": "Color"
		}],
		"table": {
			"table_columns": [{
				"column_id": "Color",
				"headline_aggregation": "COUNT_DISTINCT"
			}, {
				"column_id": "Total Revenue",
				"headline_aggregation": "SUM"
			}],
			"ordered_column_ids": ["Color", "Total Revenue"]
		},
		"chart": {
			"type": "COLUMN",
			"chart_columns": [{
				"column_id": "Total Revenue"
			}, {
				"column_id": "Color"
			}],
			"axis_configs": [{
				"x": ["Color"],
				"y": ["Total Revenue"]
			}]
		},
		"display_mode": "TABLE_MODE"
	}
}]'
--data-urlencode 'import_policy=PARTIAL'
--data-urlencode 'force_create=true'
'http://{ThoughtSpot-Host}/callosum/v1/tspublic/v1/metadata/tml/import'
Request URL
https://{ThoughtSpot-Host}/callosum/v1/tspublic/v1/metadata/tml/import

Example responsešŸ”—

{
  "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"
        }
      }
    }
  ]
}

Response codesšŸ”—

HTTP status codeDescription

200

Successful import of the TML object representations

400

Bad request

401

Unauthorized or wrong credentials

403

Forbidden - incorrect permissions

404

Not found

500

Internal server error

Export TMLšŸ”—

To export TML objects, use the /tspublic/v1/metadata/tml/export API endpoint.

Resource URLšŸ”—

POST /tspublic/v1/metadata/tml/export

Request parametersšŸ”—

Form parameterDescriptionDefault

export_ids

String. JSON array of the IDs of objects to export. An x-www-form-urlencoded string containing a JSON array of ids of objects to export. You receive results in the order you request them.

For example:

  • To export a single object, ["226abd2843-afef-4c2f-bf2f-8fba065330e"]

  • To export multiple objects, ["226abd2843-afef-4c2f-bf2f-8fba065330e", ā€22d305bc51-688b-414f-badc-94579d48308cā€]

None

formattype

String. The format in which to export the objects. Valid values are JSON and YAML.

YAML

export_associated

Boolean. Specifies if you would like to export the associated objects. To export the objects associated with the objects specified in export_ids, set the value to true. When set to true, the API exports any underlying worksheets, tables, or views for a given object. By default, the API does not export these underlying objects.

false

export_fqn

Boolean. When set to 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 Worksheet.
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 worksheets with the same name, the TML import for a Liveboard that uses one of these worksheets would fail unless the Liveboard TML includes the FQN of the referenced Worksheet.

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.

Note

When you try to import multiple objects in bulk and create objects using the force_create attribute, the new object may refer to an existing object with the same FQN in the ThoughtSpot system instead of the other objects provided in the TML import request. For example, when you upload a TML representation of a Liveboard and the associated Worksheet with the FQNs obtained from the TML export API, the imported Liveboard may refer to an existing Worksheet with the same FQN in the ThoughtSpot system instead of the new Worksheet created during the TML import.
If you want the new objects created during the TML import to refer to the other associated objects created during the same import operation, set the export_fqn attribute to false during TML export or remove the FQNs manually before the TML import.

false

Example requestšŸ”—

Make sure the API request has the following headers:

  • The Accept header is set as Accept: text/plain

  • The X-requested-by header must be X-Requested-By: ThoughtSpot

cURL
curl -X POST
--header 'Accept: text/plain' \
--header 'X-Requested-By: ThoughtSpot' \
--data-urlencode 'export_ids=["12289fad-f230-485e-8c65-e36082eebf44"]' \
--data-urlencode 'formattype=JSON' \
--data-urlencode 'export_associated=false' \
--data-urlencode 'export_fqn=true' \
'http://{ThoughtSpot-Host}/callosum/v1/tspublic/v1/metadata/tml/export'
Request URL
https://{ThoughtSpot-Host}/callosum/v1/tspublic/v1/metadata/tml/export

Example responsešŸ”—

{
   "object":[
      {
         "info":{
            "name":"Total sales",
            "filename":"Total sales.pinboard.tml",
            "status":{
               "status_code":"OK"
            },
            "type":"pinboard",
            "id":"bf3b1f36-b96e-4aa7-b619-b7743c8bd15c"
         },
         "edoc":"{\"guid\": \"bf3b1f36-b96e-4aa7-b619-b7743c8bd15c\",\"liveboard\": {\"name\": \"Total sales\",\"visualizations\": [{\"id\": \"Viz_1\",\"answer\": {\"name\": \"Total sales by store\",\"tables\": [{\"id\": \"(Sample) Retail - Apparel\",\"name\": \"(Sample) Retail - Apparel\",\"fqn\": \"cd252e5c-b552-49a8-821d-3eadaa049cca\"}],\"search_query\": \"[sales] [store] [state]\",\"answer_columns\": [{\"name\": \"state\"},{\"name\": \"store\"},{\"name\": \"Total sales\"}],\"table\": {\"table_columns\": [{\"column_id\": \"store\",\"show_headline\": false},{\"column_id\": \"state\",\"show_headline\": false},{\"column_id\": \"Total sales\",\"show_headline\": false}],\"ordered_column_ids\": [\"store\",\"state\",\"Total sales\"],\"client_state\": \"\",\"client_state_v2\": \"{\\\"tableVizPropVersion\\\": \\\"V1\\\"}\"},\"chart\": {\"type\": \"GEO_AREA\",\"chart_columns\": [{\"column_id\": \"store\"},{\"column_id\": \"state\"},{\"column_id\": \"Total sales\"}],\"axis_configs\": [{\"x\": [\"state\"],\"y\": [\"Total sales\"]}],\"client_state\": \"\",\"client_state_v2\": \"{\\\"version\\\": \\\"V4DOT2\\\",\\\"chartProperties\\\": {\\\"mapviewport\\\": {\\\"center\\\": [-1.0815372462017208E7,4944187.994859374],\\\"zoomLevel\\\": 5.140063818579165},\\\"responsiveLayoutPreference\\\": \\\"AUTO_ON\\\",\\\"chartSpecific\\\": {}},\\\"axisProperties\\\": [{\\\"id\\\": \\\"be5fe824-1a94-4fc4-88f6-501198708122\\\",\\\"properties\\\": {\\\"axisType\\\": \\\"Y\\\",\\\"linkedColumns\\\": [\\\"Total sales\\\"],\\\"isOpposite\\\": false}},{\\\"id\\\": \\\"474621ab-c78c-496f-aa71-8de82a5a1af4\\\",\\\"properties\\\": {\\\"axisType\\\": \\\"X\\\",\\\"linkedColumns\\\": [\\\"state\\\"]}}],\\\"systemSeriesColors\\\": [{\\\"serieName\\\": \\\"Total sales\\\",\\\"color\\\": \\\"#48D1E0\\\"}],\\\"systemMultiColorSeriesColors\\\": [{\\\"serieName\\\": \\\"Total sales\\\",\\\"colorMap\\\": [{\\\"serieName\\\": \\\"state\\\",\\\"color\\\": [\\\"#ffffb2\\\",\\\"#fddd87\\\",\\\"#fba35d\\\",\\\"#f75534\\\",\\\"#f9140a\\\",\\\"#d70315\\\",\\\"#b10026\\\"]}]}]}\"},\"display_mode\": \"CHART_MODE\"}},{\"id\": \"Viz_2\",\"answer\": {\"name\": \"Total sales by store\",\"tables\": [{\"id\": \"(Sample) Retail - Apparel\",\"name\": \"(Sample) Retail - Apparel\",\"fqn\": \"cd252e5c-b552-49a8-821d-3eadaa049cca\"}],\"search_query\": \"[sales] [store] [quantity purchased]\",\"answer_columns\": [{\"name\": \"store\"},{\"name\": \"Total quantity purchased\"},{\"name\": \"Total sales\"}],\"table\": {\"table_columns\": [{\"column_id\": \"store\",\"show_headline\": false},{\"column_id\": \"Total sales\",\"show_headline\": false},{\"column_id\": \"Total quantity purchased\",\"show_headline\": false}],\"ordered_column_ids\": [\"store\",\"Total sales\",\"Total quantity purchased\"],\"client_state\": \"\",\"client_state_v2\": \"{\\\"tableVizPropVersion\\\": \\\"V1\\\"}\"},\"chart\": {\"type\": \"COLUMN\",\"chart_columns\": [{\"column_id\": \"store\"},{\"column_id\": \"Total sales\"},{\"column_id\": \"Total quantity purchased\"}],\"axis_configs\": [{\"x\": [\"store\"],\"y\": [\"Total sales\",\"Total quantity purchased\"]}],\"client_state\": \"\",\"client_state_v2\": \"{\\\"version\\\": \\\"V4DOT2\\\",\\\"chartProperties\\\": {\\\"responsiveLayoutPreference\\\": \\\"AUTO_ON\\\",\\\"chartSpecific\\\": {}},\\\"axisProperties\\\": [{\\\"id\\\": \\\"6cac31dc-bf75-4e9e-ab96-422053d913cd\\\",\\\"properties\\\": {\\\"axisType\\\": \\\"Y\\\",\\\"linkedColumns\\\": [\\\"Total sales\\\"],\\\"isOpposite\\\": false}},{\\\"id\\\": \\\"5f5971ce-7e5f-48a0-9ba4-2c376699f64c\\\",\\\"properties\\\": {\\\"axisType\\\": \\\"Y\\\",\\\"linkedColumns\\\": [\\\"Total quantity purchased\\\"],\\\"isOpposite\\\": true}},{\\\"id\\\": \\\"23799dc2-3d6c-4da1-9d1b-e1dba0e5cc00\\\",\\\"properties\\\": {\\\"axisType\\\": \\\"X\\\",\\\"linkedColumns\\\": [\\\"store\\\"]}}],\\\"systemSeriesColors\\\": [{\\\"serieName\\\": \\\"Total sales\\\",\\\"color\\\": \\\"#48D1E0\\\"},{\\\"serieName\\\": \\\"Total quantity purchased\\\",\\\"color\\\": \\\"#2E75F0\\\"}],\\\"systemMultiColorSeriesColors\\\": [{\\\"serieName\\\": \\\"Total sales\\\",\\\"colorMap\\\": [{\\\"serieName\\\": \\\"a3882487-1509-4b13-8430-2e91d511a865\\\",\\\"color\\\": [\\\"#ffffb2\\\",\\\"#fddd87\\\",\\\"#fba35d\\\",\\\"#f75534\\\",\\\"#f9140a\\\",\\\"#d70315\\\",\\\"#b10026\\\"]}]}]}\"},\"display_mode\": \"CHART_MODE\"}}]}}"
      }
   ]
}

Response codesšŸ”—

HTTP status codeDescription

200

Successful TML export operation

400

Bad request

401

Unauthorized - wrong credentials

403

Forbidden - incorrect permissions

404

Not found

500

Internal server error