Java SDK for REST APIs

Java SDK for REST APIs

The REST API Java SDK provides a client library to interact with ThoughtSpot REST API v2 endpoints from Java applications.

Before you begin🔗

Before you begin, check if your setup meets the following requirements:

  • Your application setup has the necessary tools and environments for installing, deploying, and testing the SDK integration.

  • The REST API Java SDK library supports Java 8 and later. Ensure that your environment has Java 8 or later installed.

  • You have access to the necessary repositories on GitHub and Maven Central and network permissions download dependencies.

  • You have a ThoughtSpot instance with access to v2 REST APIs.
    For token-based authentication, you’ll need access to the secret key.

  • User privileges and object permissions to view, edit, or create ThoughtSpot objects and resources.

Import the SDK to your application environment🔗

If you are using Maven, add the REST API Java SDK as a dependency to the POM.xml file in your project:

<dependency>
  <groupId>io.github.thoughtspot</groupId>
  <artifactId>rest-api-sdk-lib</artifactId>
  <version>2.14.0</version> <!-- Use the latest version available -->
  <scope>compile</scope>
</dependency>

If you are using Gradle, add the REST API Java SDK as a dependency to your build file:

repositories {
  mavenCentral()
}

dependencies {
   implementation "io.github.thoughtspot:rest-api-sdk-lib:2.14.0"
   // Use the latest version of the SDK
}

API client configuration🔗

The ApiClientConfiguration class in the REST API Java SDK allows configuring the settings required for API clients to call REST APIs from their application context. Use this class to specify any of the following methods and parameters:

  • basePath - Sets the base path for API requests.

  • bearerToken - Sets bearer tokens to authenticate API requests.

  • bearerTokenSupplier - Sets the bearer token supplier for authentication.

  • defaultHeader - Adds a default header to API requests.

  • defaultHeaderMap - Sets a map of default headers to include in the API requests.

  • defaultCookie - Adds a default cookie to the client configuration.

  • defaultCookieMap - Sets a map of default cookies in the client configuration.

  • verifyingSsl - Enables Secure Sockets Layer (SSL) certificate verification for API requests.

  • sslCaCert - Configures the client to use a specific input stream that contains the SSL CA certificate.

  • keyManager - Adds a key manager to the client configuration.

  • keyManagers - Adds a list of key managers to the client configuration.

  • downloadPath - Sets the download path for files.

  • connectTimeoutMillis - Sets the connection timeout.

  • readTimeoutMillis - Configures the maximum number of seconds the client will wait for a response after sending a request before timing out.

  • writeTimeoutMillis - Configures the maximum number of milliseconds the client will wait for the data to be written to the server after sending a request before timing out.

// Create configuration for the ThoughtSpot API client
        ApiClientConfiguration apiClientConfiguration = new ApiClientConfiguration.Builder()
                .basePath(BASE_PATH) // Your ThoughtSpot application URL
                .verifyingSsl(false) // Disable SSL verification for testing purposes
                .readTimeoutMillis(30000) // Extended read timeout to 30 seconds
                .build();

Authentication🔗

The REST API v2.0 supports various authentication methods. The most common method used for automation and application integration is the token-based authentication. To get a token from from authentication token endpoint, you need to specify the username and password or secret_key.

The following example shows the code for getting an authentication token by passing username and password, and creating a user session using this token:

package org.example;

// Import classes:
import com.thoughtspot.client.ApiClientConfiguration;
import com.thoughtspot.client.ApiException;
import com.thoughtspot.client.api.ThoughtSpotRestApi;
import com.thoughtspot.client.model.GetFullAccessTokenRequest;
import com.thoughtspot.client.model.Token;
import com.thoughtspot.client.model.User;

public class Example {
  private static final String BASE_PATH = *CLUSTER_URL*; // Your ThoughtSpot application URL
  private static final String USERNAME = "tsUserA"; // Username
  private static final String PASSWORD = "Your-Password"; // Password

  public static void main(String[] args) {
    try {
        // Create configuration for the ThoughtSpot API client
        ApiClientConfiguration apiClientConfiguration = new ApiClientConfiguration.Builder()
                .basePath(BASE_PATH)
                .verifyingSsl(false) // Disable SSL verification for testing purposes
                .readTimeoutMillis(30000) // Extended read timeout to 30 seconds
                .build();

        // Create an instance of the ThoughtSpot API client
        ThoughtSpotRestApi tsRestApi = new ThoughtSpotRestApi(apiClientConfiguration);

        // Authenticate the user and retrieve the full access token
        GetFullAccessTokenRequest getFullAccessTokenRequest = new GetFullAccessTokenRequest()
                .username(USERNAME)
                .password(PASSWORD);
        Token response = tsRestApi.getFullAccessToken(getFullAccessTokenRequest);

        // Update the API client configuration with the access token
        apiClientConfiguration = apiClientConfiguration.toBuilder()
                .bearerTokenSupplier(response::getToken) // You can pass your own token supplier here
                .build();

        // Apply the updated configuration to the ThoughtSpot API client
        tsRestApi.applyApiClientConfiguration(apiClientConfiguration);

       // Current user information
        User currentUser = tsRestApi.getCurrentUserInfo();
        System.out.println("Current User: " + currentUser.toJson());

        // Optionally, use .{REQUEST}WithHttpInfo() to get response details
        ApiResponse<User> currentUserResponse = tsRestApi.getCurrentUserInfoWithHttpInfo();
        System.out.println("Current User: " + currentUserResponse.getData().toString());
        System.out.println("Status code: " + currentUserResponse.getStatusCode());
        System.out.println("Response headers: " + currentUserResponse.getHeaders().toString());
    } catch (ApiException e) {
        System.err.println("Exception when calling ThoughtSpot API");
        System.err.println("Status code: " + e.getCode());
        System.err.println("Reason: " + e.getResponseBody());
        System.err.println("Response headers: " + e.getResponseHeaders());
        e.printStackTrace();
    }
  }
}

You can also obtain a token by sending username and secret_key in your authentication token request. The secret key is generated when Trusted authentication is enabled on your instance and can be viewed on the Develop > Security Settings page.

The following example shows the code for getting an authentication token by passing username and secret_key, and creating a user session using this token:

package org.example;

// Import classes:
import com.thoughtspot.client.ApiClientConfiguration;
import com.thoughtspot.client.ApiException;
import com.thoughtspot.client.api.ThoughtSpotRestApi;
import com.thoughtspot.client.model.GetFullAccessTokenRequest;
import com.thoughtspot.client.model.Token;
import com.thoughtspot.client.model.User;

public class Example {
  private static final String BASE_PATH = *CLUSTER_URL*; // Your ThoughtSpot application URL
  private static final String USERNAME = "tsUserA"; // Username
  private static final String SECRET_KEY = "YOUR_SECRET_KEY"; // Secret key generated for your instance

  public static void main(String[] args) {
    try {
        // Create configuration for the ThoughtSpot API client
        ApiClientConfiguration apiClientConfiguration = new ApiClientConfiguration.Builder()
                .basePath(BASE_PATH)
                .verifyingSsl(false) // Disable SSL verification for testing only
                .readTimeoutMillis(30000)
                .build();

        // Create an instance of the ThoughtSpot API client
        ThoughtSpotRestApi tsRestApi = new ThoughtSpotRestApi(apiClientConfiguration);

        // Authenticate the user and retrieve the full access token using secret_key
        GetFullAccessTokenRequest getFullAccessTokenRequest = new GetFullAccessTokenRequest()
                .username(USERNAME)
                .secretKey(SECRET_KEY); // Use secretKey. Do not use password

        Token response = tsRestApi.getFullAccessToken(getFullAccessTokenRequest);

        // Update the API client configuration with the access token
        apiClientConfiguration = apiClientConfiguration.toBuilder()
                .bearerTokenSupplier(response::getToken)
                .build();

        // Apply the updated configuration to the ThoughtSpot API client
        tsRestApi.applyApiClientConfiguration(apiClientConfiguration);

        // Current user information
        User currentUser = tsRestApi.getCurrentUserInfo();
        System.out.println("Current User: " + currentUser.toJson());
    } catch (ApiException e) {
        System.err.println("Exception when calling ThoughtSpot API");
        System.err.println("Status code: " + e.getCode());
        System.err.println("Reason: " + e.getResponseBody());
        System.err.println("Response headers: " + e.getResponseHeaders());
        e.printStackTrace();
    }
  }
}

Create a test API request🔗

Make a test API call to test the integration and verify the response.

In this example, we’ll use the CreateUserRequest object to create a user.

package org.example;

import com.thoughtspot.client.ApiClientConfiguration;
import com.thoughtspot.client.ApiException;
import com.thoughtspot.client.api.ThoughtSpotRestApi;
import com.thoughtspot.client.model.CreateUserRequest;
import com.thoughtspot.client.model.User;

public class AddUserExample {
    private static final String BASE_PATH = *CLUSTER_URL*; // Your ThoughtSpot application instance
    private static final String BEARER_TOKEN = "YOUR_AUTH_TOKEN"; // Token obtained from ThoughtSpot to authorize your API calls

    public static void main(String[] args) {
        try {
            // Configure the API client with the bearer token
            ApiClientConfiguration apiClientConfiguration = new ApiClientConfiguration.Builder()
                    .basePath(BASE_PATH)
                    .bearerTokenSupplier(() -> BEARER_TOKEN)
                    .verifyingSsl(false) // For testing only; enable SSL in production
                    .readTimeoutMillis(30000)
                    .build();

            // Create an instance of the ThoughtSpot API client
            ThoughtSpotRestApi tsRestApi = new ThoughtSpotRestApi(apiClientConfiguration);

            // Build the user creation request
            CreateUserRequest createUserRequest = new CreateUserRequest()
                    .name("[email protected]")
                    .displayName("User A")
                    .password("StrongPassword123!") // Set an initial password
                    .groupIdentifiers(Arrays.asList("sales", "marketing")) // Optional: assign groups
                    .addOrgIdentifiersItem(Org_ID); // Optional: set Org ID if using a multi-tenant instance

            // Create the user
            User createdUser = tsRestApi.createUser(createUserRequest);

            // Output the created user details
            System.out.println("User created: " + createdUser.toJson());
        } catch (ApiException e) {
            System.err.println("Exception when calling ThoughtSpot API");
            System.err.println("Status code: " + e.getCode());
            System.err.println("Reason: " + e.getResponseBody());
            System.err.println("Response headers: " + e.getResponseHeaders());
            e.printStackTrace();
        }
    }
}

Error handling🔗

The SDK raises an exception when an API request fails. Inspect the HTTP status code, response body, and response headers to determine the cause of the failure and respond appropriately. Catching exceptions is a standard way to handle these errors. The code samples in this document show how to handle errors using the ApiException class.

Supported versions🔗

Note the recommendation of Java SDK:

ThoughtSpot release versionSupported SDK version

ThoughtSpot Cloud: 10.9.0.cl

v2.14.0 or later

ThoughtSpot Cloud: 10.10.0.cl

v2.15.0 or later

SDK Reference🔗

MethodHTTP request

activateUser

POST /api/rest/2.0/users/activate

assignChangeAuthor

POST /api/rest/2.0/security/metadata/assign

assignTag

POST /api/rest/2.0/tags/assign

changeUserPassword

POST /api/rest/2.0/users/change-password

commitBranch

POST /api/rest/2.0/vcs/git/branches/commit

convertWorksheetToModel

POST /api/rest/2.0/metadata/worksheets/convert

copyObject

POST /api/rest/2.0/metadata/copyobject

createConfig

POST /api/rest/2.0/vcs/git/config/create

createConnection

POST /api/rest/2.0/connection/create

createConversation

POST /api/rest/2.0/ai/conversation/create

createCustomAction

POST /api/rest/2.0/customization/custom-actions

createOrg

POST /api/rest/2.0/orgs/create

createRole

POST /api/rest/2.0/roles/create

createSchedule

POST /api/rest/2.0/schedules/create

createTag

POST /api/rest/2.0/tags/create

createUser

POST /api/rest/2.0/users/create

createUserGroup

POST /api/rest/2.0/groups/create

dbtConnection

POST /api/rest/2.0/dbt/dbt-connection

dbtGenerateSyncTml

POST /api/rest/2.0/dbt/generate-sync-tml

dbtGenerateTml

POST /api/rest/2.0/dbt/generate-tml

dbtSearch

POST /api/rest/2.0/dbt/search

deactivateUser

POST /api/rest/2.0/users/deactivate

deleteConfig

POST /api/rest/2.0/vcs/git/config/delete

deleteConnection

POST /api/rest/2.0/connection/delete

deleteConnectionV2

POST /api/rest/2.0/connections/{connection_identifier}/delete

deleteCustomAction

POST /api/rest/2.0/customization/custom-actions/{custom_action_identifier}/delete

deleteDbtConnection

POST /api/rest/2.0/dbt/{dbt_connection_identifier}/delete

deleteMetadata

POST /api/rest/2.0/metadata/delete

deleteOrg

POST /api/rest/2.0/orgs/{org_identifier}/delete

deleteRole

POST /api/rest/2.0/roles/{role_identifier}/delete

deleteSchedule

POST /api/rest/2.0/schedules/{schedule_identifier}/delete

deleteTag

POST /api/rest/2.0/tags/{tag_identifier}/delete

deleteUser

POST /api/rest/2.0/users/{user_identifier}/delete

deleteUserGroup

POST /api/rest/2.0/groups/{group_identifier}/delete

deployCommit

POST /api/rest/2.0/vcs/git/commits/deploy

downloadConnectionMetadataChanges

POST /api/rest/2.0/connections/download-connection-metadata-changes/{connection_identifier}

exportAnswerReport

POST /api/rest/2.0/report/answer

exportLiveboardReport

POST /api/rest/2.0/report/liveboard

exportMetadataTML

POST /api/rest/2.0/metadata/tml/export

exportMetadataTMLBatched

POST /api/rest/2.0/metadata/tml/export/batch

fetchAnswerData

POST /api/rest/2.0/metadata/answer/data

fetchAnswerSqlQuery

POST /api/rest/2.0/metadata/answer/sql

fetchAsyncImportTaskStatus

POST /api/rest/2.0/metadata/tml/async/status

fetchConnectionDiffStatus

POST /api/rest/2.0/connections/fetch-connection-diff-status/{connection_identifier}

fetchLiveboardData

POST /api/rest/2.0/metadata/liveboard/data

fetchLiveboardSqlQuery

POST /api/rest/2.0/metadata/liveboard/sql

fetchLogs

POST /api/rest/2.0/logs/fetch

fetchPermissionsOfPrincipals

POST /api/rest/2.0/security/principals/fetch-permissions

fetchPermissionsOnMetadata

POST /api/rest/2.0/security/metadata/fetch-permissions

forceLogoutUsers

POST /api/rest/2.0/users/force-logout

getCurrentUserInfo

GET /api/rest/2.0/auth/session/user

getCurrentUserToken

GET /api/rest/2.0/auth/session/token

getCustomAccessToken

POST /api/rest/2.0/auth/token/custom

getFullAccessToken

POST /api/rest/2.0/auth/token/full

getObjectAccessToken

POST /api/rest/2.0/auth/token/object

getSystemConfig

GET /api/rest/2.0/system/config

getSystemInformation

GET /api/rest/2.0/system

getSystemOverrideInfo

GET /api/rest/2.0/system/config-overrides

importMetadataTML

POST /api/rest/2.0/metadata/tml/import

importMetadataTMLAsync

POST /api/rest/2.0/metadata/tml/async/import

importUserGroups

POST /api/rest/2.0/groups/import

importUsers

POST /api/rest/2.0/users/import

login

POST /api/rest/2.0/auth/session/login

logout

POST /api/rest/2.0/auth/session/logout

queryGetDecomposedQuery

POST /api/rest/2.0/ai/analytical-questions

resetUserPassword

POST /api/rest/2.0/users/reset-password

revertCommit

POST /api/rest/2.0/vcs/git/commits/{commit_id}/revert

revokeToken

POST /api/rest/2.0/auth/token/revoke

searchCommits

POST /api/rest/2.0/vcs/git/commits/search

searchConfig

POST /api/rest/2.0/vcs/git/config/search

searchConnection

POST /api/rest/2.0/connection/search

searchCustomActions

POST /api/rest/2.0/customization/custom-actions/search

searchData

POST /api/rest/2.0/searchdata

searchMetadata

POST /api/rest/2.0/metadata/search

searchOrgs

POST /api/rest/2.0/orgs/search

searchRoles

POST /api/rest/2.0/roles/search

searchSchedules

POST /api/rest/2.0/schedules/search

searchTags

POST /api/rest/2.0/tags/search

searchUserGroups

POST /api/rest/2.0/groups/search

searchUsers

POST /api/rest/2.0/users/search

sendMessage

POST /api/rest/2.0/ai/conversation/{conversation_identifier}/converse

shareMetadata

POST /api/rest/2.0/security/metadata/share

singleAnswer

POST /api/rest/2.0/ai/answer/create

unassignTag

POST /api/rest/2.0/tags/unassign

updateConfig

POST /api/rest/2.0/vcs/git/config/update

updateConnection

POST /api/rest/2.0/connection/update

updateConnectionV2

POST /api/rest/2.0/connections/{connection_identifier}/update

updateCustomAction

POST /api/rest/2.0/customization/custom-actions/{custom_action_identifier}/update

updateDbtConnection

POST /api/rest/2.0/dbt/update-dbt-connection

updateMetadataHeader

POST /api/rest/2.0/metadata/headers/update

updateMetadataObjId

POST /api/rest/2.0/metadata/update-obj-id

updateOrg

POST /api/rest/2.0/orgs/{org_identifier}/update

updateRole

POST /api/rest/2.0/roles/{role_identifier}/update

updateSchedule

POST /api/rest/2.0/schedules/{schedule_identifier}/update

updateSystemConfig

POST /api/rest/2.0/system/config-update

updateTag

POST /api/rest/2.0/tags/{tag_identifier}/update

updateUser

POST /api/rest/2.0/users/{user_identifier}/update

updateUserGroup

POST /api/rest/2.0/groups/{group_identifier}/update

validateMerge

POST /api/rest/2.0/vcs/git/branches/validate

validateToken

POST /api/rest/2.0/auth/token/validate