Like what you see? Have a play with our trial version.

Yellowfin supports a multi-tenant structure through the creation of Client Organizations. You can read about Client Organizations here.

A common integration scenario is to create new clients programmatically. This could be valid in a SaaS scenario where a new client has been onboarded.  The specific code that handles this in the host application could be modified to also create a corresponding Yellowfin Client Organization at the same time. 

Another common scenario is when a new user is created in the host application. If the user needs to be attached to an existing Tenant, then Yellowfin services can be used to associate that user with a corresponding Client Organization.

Creating a new Client Organization

A new Client Organization can be created using the POST /api/orgs end-pointCreate Org. This end-point accepts the following payload:

{
  "clientRefId": "CLIENT5",
  "name": "Client 5",
  "defaultTimezone": "AUSTRALIA/SYDNEY",
  "customStylePath": "client5stylePath"
}

The clientRefId attribute is the primary identifier for the new tenant. The name attribute is the display name for the new tenant. The defaultTimezone attribute specifies the timezone for the new tenant, but this is not mandatory. A tenant will inherit the primary organization’s timezone if this is not set. The customStylePath defines a directory where custom styles and images will be stored for this tenant. This is not mandatory.

The following code examples create a new Client Organization.

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Create a new Client Organization using the Yellowfin REST API
 */
public class CreateClientOrg {
    public static void main(String[] args) throws Exception {

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String newTenantName = ""New Client"";
        String newTenantCode = ""NEWCLIENT"";

        String token = generateToken(host, restUsername, restPassword);

        String createTenantPayload =
                ""{"" +
                        ""  \""clientRefId\"": \"""" + newTenantCode + ""\"","" +
                        ""  \""name\"": \"""" + newTenantName + ""\"","" +
                        ""  \""defaultTimezone\"": \""AUSTRALIA/SYDNEY\"","" +
                        ""  \""customStylePath\"": \""newClientStylePath\"" "" +
                        ""}"";

        System.out.println(""Payload: "" + createTenantPayload);

        Content c = Request.post(host + ""/api/orgs"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(createTenantPayload, null)
                .execute().returnContent();

        System.out.print(c.asString());

    }



    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class CreateClientOrg
    {
        static async Task Main(string[] args)
        {
            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";

            string newTenantName = ""New Client"";
            string newTenantCode = ""NEWCLIENT"";

            string token = await GenerateToken(host, restUsername, restPassword);

            string createTenantPayload = ""{"" +
                ""  \""clientRefId\"": \"""" + newTenantCode + ""\"","" +
                ""  \""name\"": \"""" + newTenantName + ""\"","" +
                ""  \""defaultTimezone\"": \""AUSTRALIA/SYDNEY\"","" +
                ""  \""customStylePath\"": \""newClientStylePath\"" "" +
                ""}"";

            Console.WriteLine(""Payload: "" + createTenantPayload);

            long nonce = new Random().NextInt64();

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "" , nonce="" + nonce + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                var content = new StringContent(createTenantPayload, System.Text.Encoding.UTF8, ""application/json"");

                HttpResponseMessage response = await httpClient.PostAsync(host + ""/api/orgs"", content);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine(""Failed to create client org. Status code: "" + response.StatusCode);
                }
            }
        }

        static async Task<string> GenerateToken(string host, string username, string password)
        {
            using (var client = new HttpClient())
            {
                // Generate nonce
                long nonce = new Random().NextInt64();

                // Create HTTP request
                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Add(""Authorization"", ""YELLOWFIN ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "", nonce="" + nonce);
                request.Headers.Add(""Accept"", ""application/vnd.yellowfin.api-v1+json"");
                request.Content = new StringContent(
                    JsonConvert.SerializeObject(new { userName = username, password = password }),
                    System.Text.Encoding.UTF8,
                    ""application/json""
                );

                // Send request and get response
                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                // Parse JSON response
                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                }
                else
                {
                    Console.WriteLine(""Token not retrieved"");
                    Environment.Exit(-1);
                }

                return accessToken;
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""

	newTenantName := ""New Client""
	newTenantCode := ""NEWCLIENT""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	fmt.Println(""Payload:"", createTenantPayload(newTenantCode, newTenantName))

	client := &http.Client{}
	reqBody := createTenantPayload(newTenantCode, newTenantName)
	req, err := http.NewRequest(""POST"", host+""/api/orgs"", bytes.NewBuffer(reqBody))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	fmt.Println(string(body))
}

func generateToken(host, restUsername, restPassword string) (string, error) {
	// Generate nonce
	nonce := rand.Int63()

	// Create request body
	requestBody, err := json.Marshal(map[string]string{
		""userName"": restUsername,
		""password"": restPassword,
	})
	if err != nil {
		fmt.Println(""Error marshaling request body:"", err)
		return """", err
	}

	// Create HTTP client
	client := &http.Client{}

	// Create HTTP request
	request, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return """", err
	}

	// Add request headers
	request.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	request.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	request.Header.Set(""Content-Type"", ""application/json"")

	// Send HTTP request
	response, err := client.Do(request)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return """", err
	}
	defer response.Body.Close()

	// Read response body
	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return """", err
	}

	// Parse JSON response
	var jsonResponse map[string]interface{}
	err = json.Unmarshal(responseBody, &jsonResponse)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return """", err
	}

	// Get access token from response
	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		fmt.Println(""Token not retrieved"")
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	return accessToken, nil
}

func createTenantPayload(newTenantCode, newTenantName string) []byte {
	payload := fmt.Sprintf(""{\""clientRefId\"": \""%s\"", \""name\"": \""%s\"", \""defaultTimezone\"": \""AUSTRALIA/SYDNEY\"", \""customStylePath\"": \""newClientStylePath\"" }"", newTenantCode, newTenantName)
	return []byte(payload)
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const newTenantName = ""New Client"";
    const newTenantCode = ""NEWCLIENT"";

    const token = await generateToken(host, restUsername, restPassword);

    if (token === null) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    const createTenantPayload = `{
        ""clientRefId"": ""${newTenantCode}"",
        ""name"": ""${newTenantName}"",
        ""defaultTimezone"": ""AUSTRALIA/SYDNEY"",
        ""customStylePath"": ""newClientStylePath""
    }`;

    console.log(""Payload:"", createTenantPayload);

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/orgs`, {
            method: 'POST',
            headers: headers,
            body: createTenantPayload
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        console.log(responseBody);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function generateToken(host, restUsername, restPassword) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: restUsername,
        password: restPassword
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
        } else {
            console.log(""Token not retrieved"");
        }

        return accessToken;
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

main();
PHP
<?php
function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $newTenantName = ""New Client"";
    $newTenantCode = ""NEWCLIENT"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    $createTenantPayload = '{
        ""clientRefId"": ""' . $newTenantCode . '"",
        ""name"": ""' . $newTenantName . '"",
        ""defaultTimezone"": ""AUSTRALIA/SYDNEY"",
        ""customStylePath"": ""newClientStylePath""
    }';

    echo ""Payload: "" . $createTenantPayload . ""\n"";

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('POST', ""$host/api/orgs"", $headers, $createTenantPayload);
        echo $response;
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
    }
}

function generateToken($host, $restUsername, $restPassword) {
    // Generate nonce
    $nonce = mt_rand();

    // Create request body
    $requestBody = '{
        ""userName"": ""' . $restUsername . '"",
        ""password"": ""' . $restPassword . '""
    }';

    // Create request headers
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);

    // Parse JSON response
    $jsonResponse = json_decode($response, true);

    // Get access token from response
    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken;

        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main()
?>
Python
import json
import random
import time
import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    new_tenant_name = ""New Client""
    new_tenant_code = ""NEWCLIENT""

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    create_tenant_payload = '{' + \
                            f'""clientRefId"": ""{new_tenant_code}"",' + \
                            f'""name"": ""{new_tenant_name}"",' + \
                            '""defaultTimezone"": ""AUSTRALIA/SYDNEY"",' + \
                            '""customStylePath"": ""newClientStylePath""' + \
                            '}'

    print(""Payload:"", create_tenant_payload)

    nonce = random.randint(0, 2 ** 63 - 1)

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.post(host + ""/api/orgs"", headers=headers, data=create_tenant_payload)
        response.raise_for_status()
        print(response.text)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")


def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2 ** 63 - 1)

    # Create request body
    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })

    # Create request headers
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    # Send HTTP request
    response = requests.post(host + ""/api/refresh-tokens"", headers=headers, data=request_body)

    # Check response status
    if response.status_code == 200:
        # Parse JSON response
        json_response = response.json()
        access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
        print(""Access Token:"", access_token)

        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")

if __name__ == ""__main__"":
    main()

List all Tenants / Client Organizations

To list all tenants within a Yellowfin instance use the GET /api/orgs end-point Get Orgs. This lists all tenants and their properties. This can be used to find a Client Organization by other identifiers, like Client Name.

These examples list all tenants from the Yellowfin instance.

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * List Client Organizations using the Yellowfin REST API
 */
public class ListClientOrgs {
    public static void main(String[] args) throws Exception {

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String token = generateToken(host, restUsername, restPassword);

        Content c = Request.get(host + ""/api/orgs"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        System.out.print(c.asString());

    }


    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class ListClientOrgs
    {
        public static async Task Main(string[] args)
        {
            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";

            string token = await GenerateToken(host, restUsername, restPassword);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={new Random().NextInt64()}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.GetAsync(host + ""/api/orgs"");
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine(""Failed to retrieve organizations. Status code: "" + response.StatusCode);
                }
            }
        }

        private static async Task<string> GenerateToken(string host, string restUsername, string restPassword)
        {
            using (var client = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}"");
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                request.Content = new StringContent(
                    JsonConvert.SerializeObject(new { userName = restUsername, password = restPassword }),
                    System.Text.Encoding.UTF8,
                    ""application/json""
                );

                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                    return accessToken;
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                    return null;
                }
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	client := &http.Client{}
	req, err := http.NewRequest(""GET"", host+""/api/orgs"", nil)
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	fmt.Println(string(body))
}

func generateToken(host, restUsername, restPassword string) (string, error) {
	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": restUsername,
		""password"": restPassword,
	})
	if err != nil {
		fmt.Println(""Error marshaling request body:"", err)
		return """", err
	}

	client := &http.Client{}
	request, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return """", err
	}

	request.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	request.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	request.Header.Set(""Content-Type"", ""application/json"")

	response, err := client.Do(request)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return """", err
	}
	defer response.Body.Close()

	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return """", err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(responseBody, &jsonResponse)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return """", err
	}

	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		fmt.Println(""Token not retrieved"")
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	fmt.Println(""Access Token:"", accessToken)
	return accessToken, nil
}
JavaScript
const fetch = require('node-fetch');

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const token = await generateToken(host, restUsername, restPassword);

    if (token === null) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/orgs`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        console.log(responseBody);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function generateToken(host, restUsername, restPassword) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };
    const body = JSON.stringify({
        userName: restUsername,
        password: restPassword
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
            return accessToken;
        } else {
            console.log(""Token not retrieved"");
        }
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

main();
PHP
<?php
function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('GET', ""$host/api/orgs"", $headers);
        echo $response;
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
    }
}

function generateToken($host, $username, $password) {
    $nonce = mt_rand();
    $requestBody = '{""userName"":""' . $username . '"",""password"":""' . $password . '""}';
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);
    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        return $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Python
import json
import random
import time

import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    nonce = random.randint(0, 2 ** 63 - 1)

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.get(host + ""/api/orgs"", headers=headers)
        response.raise_for_status()
        print(response.text)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")


def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2 ** 63 - 1)

    # Create request body
    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })

    # Create request headers
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    # Send HTTP request
    response = requests.post(host + ""/api/refresh-tokens"", headers=headers, data=request_body)

    # Check response status
    if response.status_code == 200:
        # Parse JSON response
        json_response = response.json()
        access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
        print(""Access Token:"", access_token)

        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")

if __name__ == ""__main__"":
    main()

Grant access to a Tenant for a User

A user can be given access to a tenant using the POST /api/orgs/{tenantId}/user-access end-point Add Org User Access, where tenantId is the integer identifier for the tenant / client organization.

The required payload for the POST /api/orgs/{tenantId}/user-access end-point is:

{
   "userId": {userIpId}
}

Where {userIpId} is the integer identifier for a user.

The following code examples grant access to a client organization (identified by its clientOrgRef code) to a user (identified by their username).

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Add a User access to a Tenant using the Yellowfin REST API
 */
public class AddUserToClientOrg {
    public static void main(String[] args) throws Exception {

        System.out.print(""Add a User to a Tenant"");

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String usernameOfUserToAddtoTenant = ""user1@yellowfin.com.au"";
        String tenantClientReferenceId = ""NEWCLIENT"";

        String token = generateToken(host, restUsername, restPassword);

        Integer tenantId = retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);
        Integer userIpId = retrieveUserIpIdForUsername(host, token, usernameOfUserToAddtoTenant);

        String addUserToClientPayload = "" { \""userId\"": "" + userIpId + "" }"";

        System.out.println(""Tenant Id: "" + tenantId);
        System.out.println(""User IpId: "" + userIpId);
        System.out.println(""PayLoad: "" + addUserToClientPayload);

        Content c = Request.post(host + ""/api/orgs/"" + tenantId + ""/user-access"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(addUserToClientPayload, null)
                .execute().returnContent();

        System.out.print(c.asString());

    }
    /*
     *  This function fetches a user's integer id for a given username
     */

    public static Integer retrieveUserIpIdForUsername(String host, String token, String userName) throws IOException {

        Content c = Request.get(host + ""/api/rpc/users/user-details-by-username/"" + userName)
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong()+ "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement userIpJsonAttribute = jsonObject.get(""userId"");
        Integer userIpId = userIpJsonAttribute.getAsInt();

        return userIpId;

    }

    /*
     *  This function fetches a client organization's integer id for a given clientRefCode
     */

    public static Integer retrieveTenantIpIdForTenantName(String host, String token, String tenantCode) throws IOException {

        Content c = Request.get(host + ""/api/orgs"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement tenantList = jsonObject.get(""items"");
        JsonArray tenants = tenantList.getAsJsonArray();

        for (int i=0; i < tenants.size(); i++ ) {
            JsonObject tenant = tenants.getAsJsonArray().get(i).getAsJsonObject();
            if (!tenant.has(""clientRefId"")) continue;
            if (tenantCode.equals(tenant.get(""clientRefId"").getAsString())) return tenant.get(""ipOrg"").getAsInt();
        }

        System.out.println(""Tenant could not be found for code:"" + tenantCode);
        System.exit(-1);

        return null;
    }


    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class AddUserToClientOrg
    {
        public static async Task Main(string[] args)
        {
            Console.WriteLine(""Add a User to a Tenant"");

            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";

            string usernameOfUserToAddToTenant = ""user1@yellowfin.com.au"";
            string tenantClientReferenceId = ""NEWCLIENT"";

            string token = await GenerateToken(host, restUsername, restPassword);

            int tenantId = await RetrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);
            int userIpId = await RetrieveUserIpIdForUsername(host, token, usernameOfUserToAddToTenant);

            string addUserToClientPayload = $""{{ \""userId\"": {userIpId} }}"";

            Console.WriteLine(""Tenant Id: "" + tenantId);
            Console.WriteLine(""User IpId: "" + userIpId);
            Console.WriteLine(""PayLoad: "" + addUserToClientPayload);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={new Random().NextInt64()}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                httpClient.DefaultRequestHeaders.Add(""Content-Type"", ""application/json"");

                HttpResponseMessage response = await httpClient.PostAsync(host + ""/api/orgs/"" + tenantId + ""/user-access"", new StringContent(addUserToClientPayload, System.Text.Encoding.UTF8, ""application/json""));
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine(""Failed to add user to tenant. Status code: "" + response.StatusCode);
                }
            }
        }

        private static async Task<int> RetrieveUserIpIdForUsername(string host, string token, string userName)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={new Random().NextInt64()}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                httpClient.DefaultRequestHeaders.Add(""Content-Type"", ""application/json"");

                HttpResponseMessage response = await httpClient.GetAsync(host + ""/api/rpc/users/user-details-by-username/"" + userName);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    int userIpId = jsonObject[""userId""].Value<int>();
                    return userIpId;
                }
                else
                {
                    throw new Exception(""Failed to retrieve user ID. Status code: "" + response.StatusCode);
                }
            }
        }

        private static async Task<int> RetrieveTenantIpIdForTenantName(string host, string token, string tenantCode)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={new Random().NextInt64()}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                httpClient.DefaultRequestHeaders.Add(""Content-Type"", ""application/json"");

                HttpResponseMessage response = await httpClient.GetAsync(host + ""/api/orgs"");
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    JArray tenants = jsonObject[""items""].Value<JArray>();

                    foreach (JObject tenant in tenants)
                    {
                        if (tenant[""clientRefId""]?.Value<string>() == tenantCode)
                        {
                            return tenant[""ipOrg""].Value<int>();
                        }
                    }

                    Console.WriteLine(""Tenant could not be found for code: "" + tenantCode);
                    Environment.Exit(-1);
                }
                else
                {
                    throw new Exception(""Failed to retrieve tenant ID. Status code: "" + response.StatusCode);
                }
                return 0; // This will never be reached due to the Environment.Exit call above.
            }
        }

        private static async Task<string> GenerateToken(string host, string username, string password)
        {
            using (var client = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}"");
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                request.Content = new StringContent(JsonConvert.SerializeObject(new { userName = username, password = password }), System.Text.Encoding.UTF8, ""application/json"");

                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                    return accessToken;
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                    return null; // This will never be reached due to the Environment.Exit call above.
                }
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""os""
	""time""
)

func main() {
	fmt.Println(""Add a User to a Tenant"")

	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""

	usernameOfUserToAddToTenant := ""user1@yellowfin.com.au""
	tenantClientReferenceId := ""NEWCLIENT""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	tenantId, err := retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId)
	if err != nil {
		fmt.Println(""Error retrieving tenant ID:"", err)
		return
	}

	userIpId, err := retrieveUserIpIdForUsername(host, token, usernameOfUserToAddToTenant)
	if err != nil {
		fmt.Println(""Error retrieving user ID:"", err)
		return
	}

	addUserToClientPayload := fmt.Sprintf(`{ ""userId"": %d }`, userIpId)

	fmt.Println(""Tenant Id:"", tenantId)
	fmt.Println(""User IpId:"", userIpId)
	fmt.Println(""PayLoad:"", addUserToClientPayload)

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", fmt.Sprintf(""%s/api/orgs/%d/user-access"", host, tenantId), bytes.NewBuffer([]byte(addUserToClientPayload)))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()
	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	fmt.Println(string(body))
}

func retrieveUserIpIdForUsername(host, token, userName string) (int, error) {
	client := &http.Client{}
	req, err := http.NewRequest(""GET"", fmt.Sprintf(""%s/api/rpc/users/user-details-by-username/%s"", host, userName), nil)
	if err != nil {
		return 0, err
	}

	nonce := rand.Int63()
	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		return 0, err
	}

	userIpId, ok := jsonResponse[""userId""].(float64)
	if !ok {
		return 0, fmt.Errorf(""User ID not found in response"")
	}

	return int(userIpId), nil
}

func retrieveTenantIpIdForTenantName(host, token, tenantCode string) (int, error) {
	client := &http.Client{}
	req, err := http.NewRequest(""GET"", fmt.Sprintf(""%s/api/orgs"", host), nil)
	if err != nil {
		return 0, err
	}

	nonce := rand.Int63()
	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		return 0, err
	}

	tenants, ok := jsonResponse[""items""].([]interface{})
	if !ok {
		return 0, fmt.Errorf(""Tenant list not found in response"")
	}

	for _, tenant := range tenants {
		tenantMap, ok := tenant.(map[string]interface{})
		if !ok {
			continue
		}
		clientRefId, ok := tenantMap[""clientRefId""].(string)
		if ok && clientRefId == tenantCode {
			ipOrg, ok := tenantMap[""ipOrg""].(float64)
			if ok {
				return int(ipOrg), nil
			}
		}
	}

	fmt.Println(""Tenant could not be found for code:"", tenantCode)
	os.Exit(-1)
	return 0, nil
}

func generateToken(host, username, password string) (string, error) {
	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": username,
		""password"": password,
	})
	if err != nil {
		return """", err
	}

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", fmt.Sprintf(""%s/api/refresh-tokens"", host), bytes.NewBuffer(requestBody))
	if err != nil {
		return """", err
	}

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return """", err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return """", err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		return """", err
	}

	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    console.log(""Add a User to a Tenant"");

    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const usernameOfUserToAddtoTenant = ""user1@yellowfin.com.au"";
    const tenantClientReferenceId = ""NEWCLIENT"";

    const token = await generateToken(host, restUsername, restPassword);
    if (!token) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    const tenantId = await retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);
    const userIpId = await retrieveUserIpIdForUsername(host, token, usernameOfUserToAddtoTenant);

    const addUserToClientPayload = JSON.stringify({ userId: userIpId });

    console.log(""Tenant Id:"", tenantId);
    console.log(""User IpId:"", userIpId);
    console.log(""PayLoad:"", addUserToClientPayload);

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/orgs/${tenantId}/user-access`, {
            method: 'POST',
            headers: headers,
            body: addUserToClientPayload
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        console.log(responseBody);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function retrieveUserIpIdForUsername(host, token, userName) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/rpc/users/user-details-by-username/${userName}`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const userIpId = jsonResponse.userId;

        return userIpId;
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

async function retrieveTenantIpIdForTenantName(host, token, tenantCode) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/orgs`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const tenants = jsonResponse.items;

        for (const tenant of tenants) {
            if (tenant.clientRefId && tenant.clientRefId === tenantCode) {
                return tenant.ipOrg;
            }
        }

        console.log(""Tenant could not be found for code:"", tenantCode);
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

async function generateToken(host, restUsername, restPassword) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: restUsername,
        password: restPassword
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
        } else {
            console.log(""Token not retrieved"");
        }

        return accessToken;
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

main();
PHP
<?php

function main() {
    echo ""Add a User to a Tenant\n"";

    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $usernameOfUserToAddtoTenant = ""user1@yellowfin.com.au"";
    $tenantClientReferenceId = ""NEWCLIENT"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    try {
        $tenantId = retrieveTenantIpIdForTenantName($host, $token, $tenantClientReferenceId);
        $userIpId = retrieveUserIpIdForUsername($host, $token, $usernameOfUserToAddtoTenant);
    } catch (Exception $e) {
        echo ""Error retrieving tenant or user ID: "" . $e->getMessage();
        return;
    }

    $addUserToClientPayload = json_encode(array(""userId"" => $userIpId));

    echo ""Tenant Id: "" . $tenantId . ""\n"";
    echo ""User IpId: "" . $userIpId . ""\n"";
    echo ""PayLoad: "" . $addUserToClientPayload . ""\n"";

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('POST', ""$host/api/orgs/$tenantId/user-access"", $headers, $addUserToClientPayload);
        echo $response;
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
    }
}

function generateToken($host, $restUsername, $restPassword) {
    $nonce = mt_rand();
    $requestBody = json_encode(array(
        ""userName"" => $restUsername,
        ""password"" => $restPassword
    ));

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);
    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken . ""\n"";

        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function retrieveUserIpIdForUsername($host, $token, $userName) {
    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', ""$host/api/rpc/users/user-details-by-username/$userName"", $headers);
    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""userId""])) {
        return $jsonResponse[""userId""];
    } else {
        throw new Exception(""User ID not retrieved successfully"");
    }
}

function retrieveTenantIpIdForTenantName($host, $token, $tenantCode) {
    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', ""$host/api/orgs"", $headers);
    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""items""])) {
        $tenants = $jsonResponse[""items""];
        foreach ($tenants as $tenant) {
            if (isset($tenant[""clientRefId""]) && $tenant[""clientRefId""] === $tenantCode) {
                return $tenant[""ipOrg""];
            }
        }
    }

    throw new Exception(""Tenant could not be found for code: $tenantCode"");
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Python
import json
import random
import time
import requests


def main():
    print(""Add a User to a Tenant"")

    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    username_of_user_to_add_to_tenant = ""user1@yellowfin.com.au""
    tenant_client_reference_id = ""NEWCLIENT""

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    try:
        tenant_id = retrieve_tenant_ip_id_for_tenant_name(host, token, tenant_client_reference_id)
        user_ip_id = retrieve_user_ip_id_for_username(host, token, username_of_user_to_add_to_tenant)
    except Exception as e:
        print(f""Error retrieving tenant or user ID: {e}"")
        return

    add_user_to_client_payload = json.dumps({""userId"": user_ip_id})

    print(""Tenant Id:"", tenant_id)
    print(""User IpId:"", user_ip_id)
    print(""Payload:"", add_user_to_client_payload)

    nonce = random.randint(0, 2 ** 63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.post(f""{host}/api/orgs/{tenant_id}/user-access"", headers=headers,
                                 data=add_user_to_client_payload)
        response.raise_for_status()
        print(response.text)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")


def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2 ** 63 - 1)

    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.post(f""{host}/api/refresh-tokens"", headers=headers, data=request_body)
    response.raise_for_status()

    json_response = response.json()
    access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
    print(""Access Token:"", access_token)

    return access_token


def retrieve_user_ip_id_for_username(host, token, username):
    nonce = random.randint(0, 2 ** 63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.get(f""{host}/api/rpc/users/user-details-by-username/{username}"", headers=headers)
    response.raise_for_status()

    json_response = response.json()
    user_ip_id = json_response[""userId""]

    return user_ip_id


def retrieve_tenant_ip_id_for_tenant_name(host, token, tenant_code):
    nonce = random.randint(0, 2 ** 63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.get(f""{host}/api/orgs"", headers=headers)
    response.raise_for_status()

    json_response = response.json()
    tenants = json_response[""items""]

    for tenant in tenants:
        if ""clientRefId"" in tenant and tenant[""clientRefId""] == tenant_code:
            return tenant[""ipOrg""]

    print(f""Tenant could not be found for code: {tenant_code}"")
    exit(-1)


if __name__ == ""__main__"":
    main()

Removing access from a Tenant for a User

A user's access can be revoked from a tenant using the DELETE /api/orgs/{tenantId}/user-access/{userIpId) end-point Remove Org User Access, where tenantId is the integer identifier for the tenant / client organization, and  {userIpId} is the integer identifier for a user.

The following code examples revoke access from a client organization (identified by its clientOrgRef code) for a user (identified by their username).

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Add a User access to a Tenant using the Yellowfin REST API
 */
public class RemoveUserFromClientOrg {
    public static void main(String[] args) throws Exception {

        System.out.print(""Revoke Access to Tenant for User"");

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String usernameOfUserToRemoveFromTenant = ""user1@yellowfin.com.au"";
        String tenantClientReferenceId = ""NEWCLIENT"";

        String token = generateToken(host, restUsername, restPassword);

        Integer tenantId = retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);
        Integer userIpId = retrieveUserIpIdForUsername(host, token, usernameOfUserToRemoveFromTenant);


        System.out.println(""Tenant Id: "" + tenantId);
        System.out.println(""User IpId: "" + userIpId);

        Content c = Request.delete(host + ""/api/orgs/"" + tenantId + ""/user-access/"" + userIpId)
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        System.out.print(c.asString());

    }
    /*
     *  This function fetches a user's integer id for a given username
     */

    public static Integer retrieveUserIpIdForUsername(String host, String token, String userName) throws IOException {

        Content c = Request.get(host + ""/api/rpc/users/user-details-by-username/"" + userName)
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong()+ "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement userIpJsonAttribute = jsonObject.get(""userId"");
        Integer userIpId = userIpJsonAttribute.getAsInt();

        return userIpId;

    }

    /*
     *  This function fetches a client organization's integer id for a given clientRefCode
     */

    public static Integer retrieveTenantIpIdForTenantName(String host, String token, String tenantCode) throws IOException {

        Content c = Request.get(host + ""/api/orgs"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement groupList = jsonObject.get(""items"");
        JsonArray groups = groupList.getAsJsonArray();

        for (int i=0; i < groups.size(); i++ ) {
            JsonObject group = groups.getAsJsonArray().get(i).getAsJsonObject();
            if (!group.has(""clientRefId"")) continue;
            if (tenantCode.equals(group.get(""clientRefId"").getAsString())) return group.get(""ipOrg"").getAsInt();
        }

        System.out.println(""Tenant could not be found for code:"" + tenantCode);
        System.exit(-1);

        return null;
    }


    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class RemoveUserFromClientOrg
    {
        static async Task Main(string[] args)
        {
            Console.Write(""Revoke Access to Tenant for User"");

            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";
            string usernameOfUserToRemoveFromTenant = ""user1@yellowfin.com.au"";
            string tenantClientReferenceId = ""NEWCLIENT"";

            string token = await GenerateToken(host, restUsername, restPassword);

            int tenantId = await RetrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);
            int userIpId = await RetrieveUserIpIdForUsername(host, token, usernameOfUserToRemoveFromTenant);

            Console.WriteLine(""Tenant Id: "" + tenantId);
            Console.WriteLine(""User IpId: "" + userIpId);

            using (HttpClient httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                // Constructing the DELETE request
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, $""{host}/api/orgs/{tenantId}/user-access/{userIpId}"");
                request.Headers.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()} , nonce={nonce}, token={token}"");
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.SendAsync(request);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine($""Failed to revoke user access. Status code: {response.StatusCode}"");
                }
            }
        }

        static async Task<int> RetrieveUserIpIdForUsername(string host, string token, string userName)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                // Constructing the GET request
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, $""{host}/api/rpc/users/user-details-by-username/{userName}"");
                request.Headers.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()} , nonce={nonce}, token={token}"");
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.SendAsync(request);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    int userIpId = jsonObject[""userId""].ToObject<int>();
                    return userIpId;
                }
                else
                {
                    Console.WriteLine($""Failed to retrieve user IpId. Status code: {response.StatusCode}"");
                    throw new Exception($""Failed to retrieve user IpId. Status code: {response.StatusCode}"");
                }
            }
        }

        static async Task<int> RetrieveTenantIpIdForTenantName(string host, string token, string tenantCode)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                // Constructing the GET request
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, $""{host}/api/orgs"");
                request.Headers.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()} , nonce={nonce}, token={token}"");
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.SendAsync(request);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    JArray groups = jsonObject[""items""].ToObject<JArray>();

                    foreach (JObject group in groups)
                    {
                        if (group[""clientRefId""] != null && tenantCode.Equals(group[""clientRefId""].ToString()))
                        {
                            int tenantIpId = group[""ipOrg""].ToObject<int>();
                            return tenantIpId;
                        }
                    }

                    Console.WriteLine($""Tenant could not be found for code: {tenantCode}"");
                    Environment.Exit(-1);
                    return -1; // This line is added to avoid compiler errors, as C# requires return in all code paths.
                }
                else
                {
                    Console.WriteLine($""Failed to retrieve tenant IpId. Status code: {response.StatusCode}"");
                    throw new Exception($""Failed to retrieve tenant IpId. Status code: {response.StatusCode}"");
                }
            }
        }

        static async Task<string> GenerateToken(string host, string username, string password)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                // Constructing the POST request
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, $""{host}/api/refresh-tokens"");
                request.Headers.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()} , nonce={nonce}"");
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                request.Content = new StringContent(
                    JsonConvert.SerializeObject(new { userName = username, password = password }),
                    System.Text.Encoding.UTF8,
                    ""application/json""
                );

                HttpResponseMessage response = await httpClient.SendAsync(request);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();
                    Console.WriteLine(""Access Token: "" + accessToken);
                    return accessToken;
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                    return null;
                }
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""
	usernameOfUserToRemoveFromTenant := ""user1@yellowfin.com.au""
	tenantClientReferenceId := ""NEWCLIENT""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	tenantId, err := retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId)
	if err != nil {
		fmt.Println(""Error retrieving tenant ID:"", err)
		return
	}

	userIpId, err := retrieveUserIpIdForUsername(host, token, usernameOfUserToRemoveFromTenant)
	if err != nil {
		fmt.Println(""Error retrieving user IP ID:"", err)
		return
	}

	fmt.Println(""Tenant Id:"", tenantId)
	fmt.Println(""User IpId:"", userIpId)

	client := &http.Client{}
	req, err := http.NewRequest(""DELETE"", fmt.Sprintf(""%s/api/orgs/%d/user-access/%d"", host, tenantId, userIpId), nil)
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixNano()/int64(time.Millisecond), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	fmt.Println(string(body))
}

func retrieveUserIpIdForUsername(host, token, userName string) (int, error) {
	client := &http.Client{}
	req, err := http.NewRequest(""GET"", host+""/api/rpc/users/user-details-by-username/""+userName, nil)
	if err != nil {
		return 0, err
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixNano()/int64(time.Millisecond), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		return 0, err
	}

	userIpId := int(jsonResponse[""userId""].(float64))
	return userIpId, nil
}

func retrieveTenantIpIdForTenantName(host, token, tenantCode string) (int, error) {
	client := &http.Client{}
	req, err := http.NewRequest(""GET"", host+""/api/orgs"", nil)
	if err != nil {
		return 0, err
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixNano()/int64(time.Millisecond), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		return 0, err
	}

	items := jsonResponse[""items""].([]interface{})
	for _, item := range items {
		group := item.(map[string]interface{})
		if group[""clientRefId""] != nil && group[""clientRefId""].(string) == tenantCode {
			return int(group[""ipOrg""].(float64)), nil
		}
	}

	return 0, fmt.Errorf(""Tenant could not be found for code: %s"", tenantCode)
}

func generateToken(host, username, password string) (string, error) {
	client := &http.Client{}

	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": username,
		""password"": password,
	})
	if err != nil {
		return """", err
	}

	req, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		return """", err
	}

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixNano()/int64(time.Millisecond), nonce))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return """", err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return """", err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		return """", err
	}

	accessToken := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if accessToken == """" {
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	fmt.Println(""Access Token:"", accessToken)
	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";
    const usernameOfUserToRemoveFromTenant = ""user1@yellowfin.com.au"";
    const tenantClientReferenceId = ""NEWCLIENT"";

    try {
        const token = await generateToken(host, restUsername, restPassword);

        if (!token) {
            console.error(""Failed to retrieve access token"");
            return;
        }

        const tenantId = await retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);
        const userIpId = await retrieveUserIpIdForUsername(host, token, usernameOfUserToRemoveFromTenant);

        console.log(""Tenant Id:"", tenantId);
        console.log(""User IpId:"", userIpId);

        const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

        const headers = {
            'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
            'Accept': 'application/vnd.yellowfin.api-v1+json',
            'Content-Type': 'application/json'
        };

        const response = await fetch(`${host}/api/orgs/${tenantId}/user-access/${userIpId}`, {
            method: 'DELETE',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        console.log(responseBody);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function retrieveUserIpIdForUsername(host, token, userName) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/rpc/users/user-details-by-username/${userName}`, {
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const userIpId = jsonResponse.userId;

        return userIpId;
    } catch (error) {
        console.error(""Error:"", error.message);
        return null;
    }
}

async function retrieveTenantIpIdForTenantName(host, token, tenantCode) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/orgs`, {
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const groups = jsonResponse.items;

        for (let i = 0; i < groups.length; i++) {
            const group = groups[i];
            if (group.clientRefId && group.clientRefId === tenantCode) {
                return group.ipOrg;
            }
        }

        throw new Error(`Tenant could not be found for code: ${tenantCode}`);
    } catch (error) {
        console.error(""Error:"", error.message);
        return null;
    }
}

async function generateToken(host, username, password) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: username,
        password: password
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
        } else {
            console.log(""Token not retrieved"");
        }

        return accessToken;
    } catch (error) {
        console.error(""Error:"", error.message);
        return null;
    }
}

main();
PHP
<?php

function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $usernameOfUserToRemoveFromTenant = ""user1@yellowfin.com.au"";
    $tenantClientReferenceId = ""NEWCLIENT"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    echo ""Token: "" . $token . ""\n"";

    try {
        $tenantId = retrieveTenantIpIdForTenantName($host, $token, $tenantClientReferenceId);
        $userIpId = retrieveUserIpIdForUsername($host, $token, $usernameOfUserToRemoveFromTenant);

        echo ""Tenant Id: "" . $tenantId . ""\n"";
        echo ""User IpId: "" . $userIpId . ""\n"";

        $nonce = mt_rand();
        $headers = array(
            'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
            'Accept: application/vnd.yellowfin.api-v1+json',
            'Content-Type: application/json'
        );

        $response = httpRequest('DELETE', ""$host/api/orgs/$tenantId/user-access/$userIpId"", $headers);
        echo ""Response: "" . $response . ""\n"";

    } catch (Exception $e) {
        echo ""Error: "" . $e->getMessage();
    }
}

function retrieveUserIpIdForUsername($host, $token, $userName) {
    $nonce = mt_rand();

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', ""$host/api/rpc/users/user-details-by-username/$userName"", $headers);
    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""userId""])) {
        return $jsonResponse[""userId""];
    } else {
        throw new Exception(""User IP ID not found for username: $userName"");
    }
}

function retrieveTenantIpIdForTenantName($host, $token, $tenantCode) {
    $nonce = mt_rand();

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', ""$host/api/orgs"", $headers);
    $jsonResponse = json_decode($response, true);

    foreach ($jsonResponse[""items""] as $group) {
        if (isset($group[""clientRefId""]) && $group[""clientRefId""] === $tenantCode) {
            return $group[""ipOrg""];
        }
    }

    throw new Exception(""Tenant ID not found for tenant code: $tenantCode"");
}

function generateToken($host, $username, $password) {
    $nonce = mt_rand();

    $requestBody = json_encode(array(
        ""userName"" => $username,
        ""password"" => $password
    ));

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);
    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        return $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Python
import json
import random
import time
import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    username_of_user_to_remove_from_tenant = ""user1@yellowfin.com.au""
    tenant_client_reference_id = ""NEWCLIENT""

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    print(f""Token: {token}"")

    try:
        tenant_id = retrieve_tenant_ip_id_for_tenant_name(host, token, tenant_client_reference_id)
        user_ip_id = retrieve_user_ip_id_for_username(host, token, username_of_user_to_remove_from_tenant)

        print(f""Tenant Id: {tenant_id}"")
        print(f""User IpId: {user_ip_id}"")

        nonce = random.randint(0, 2**63 - 1)
        headers = {
            'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
            'Accept': 'application/vnd.yellowfin.api-v1+json',
            'Content-Type': 'application/json'
        }

        response = requests.delete(f""{host}/api/orgs/{tenant_id}/user-access/{user_ip_id}"", headers=headers)
        response.raise_for_status()

        print(f""Response: {response.text}"")

    except requests.RequestException as e:
        print(f""Error sending request: {e}"")
    except Exception as e:
        print(f""Error: {e}"")


def retrieve_user_ip_id_for_username(host, token, user_name):
    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.get(f""{host}/api/rpc/users/user-details-by-username/{user_name}"", headers=headers)
    response.raise_for_status()

    json_response = response.json()
    user_ip_id = json_response.get(""userId"")

    if user_ip_id is not None:
        return user_ip_id
    else:
        raise Exception(f""User IP ID not found for username: {user_name}"")


def retrieve_tenant_ip_id_for_tenant_name(host, token, tenant_code):
    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.get(f""{host}/api/orgs"", headers=headers)
    response.raise_for_status()

    json_response = response.json()
    groups = json_response.get(""items"", [])

    for group in groups:
        if ""clientRefId"" in group and group[""clientRefId""] == tenant_code:
            return group[""ipOrg""]

    raise Exception(f""Tenant ID not found for tenant code: {tenant_code}"")


def generate_token(host, username, password):
    nonce = random.randint(0, 2**63 - 1)

    request_body = json.dumps({
        ""userName"": username,
        ""password"": password
    })

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.post(f""{host}/api/refresh-tokens"", headers=headers, data=request_body)
    response.raise_for_status()

    json_response = response.json()
    access_token = json_response[""_embedded""][""accessToken""][""securityToken""]

    if access_token is not None:
        print(f""Access Token: {access_token}"")
        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")


if __name__ == ""__main__"":
    main()

List all the Users who have access to a Tenant

A list of users who have access to a tenant can be retrieved with the GET /api/orgs/{tenantId}/user-access/ end-point Get Org User Access List, where tenantId is the integer identifier for the tenant / client organization.

The following code examples list the users who have access to a specific client organization (identified by its clientOrgRef code).

Java
package rest.code.examples;


import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
* List Users who have access to a Tenant using the Yellowfin REST API
*/
public class ListUserAccessToClientOrg {
   public static void main(String[] args) throws Exception {
     
     	System.out.print(""List Users who have Access to Tenant"");
   	
	    	String host = ""http://localhost/yellowfinHead"";
	    	String restUsername = ""admin@yellowfin.com.au"";
	    	String restPassword = ""test"";
	    	
	    	String tenantClientReferenceId = ""NEWCLIENT"";
	    	
	    	String token = generateToken(host, restUsername, restPassword);
		    	
	    	Integer tenantId = retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);
	    	System.out.println(""Tenant Id: "" + tenantId);
	    	
	    	Content c = Request.get(host + ""/api/orgs/"" + tenantId + ""/user-access"")
	  	    		.addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
	  	    		.addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	  	    		.addHeader(""Content-Type"", ""application/json"")
	  	        .execute().returnContent();
	  	    	
   	    JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
   	    JsonElement userList = jsonObject.get(""items"");
	    JsonArray users = userList.getAsJsonArray();
	   
	    System.out.println(users.size() + "" user(s) have access to tenant "" + tenantClientReferenceId);
	   
	    for (int i=0; i < users.size(); i++ ) {
	    		JsonObject user = users.getAsJsonArray().get(i).getAsJsonObject();
	    		System.out.println(""User "" + user.get(""userId"").getAsInt() + "": "" + user.get(""name"").getAsString());
	    }
	   
   }
   /*
    *  This function fetches a client organization's integer id for a given clientRefCode
    */
  
   public static Integer retrieveTenantIpIdForTenantName(String host, String token, String tenantCode) throws IOException {
   	
     	Content c = Request.get(host + ""/api/orgs"")
 	    		.addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
 	    		.addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
 	    		.addHeader(""Content-Type"", ""application/json"")
 	        .execute().returnContent();
 	    	
   	    JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
   	    JsonElement groupList = jsonObject.get(""items"");
	    JsonArray groups = groupList.getAsJsonArray();
	   
	    for (int i=0; i < groups.size(); i++ ) {
	    		JsonObject group = groups.getAsJsonArray().get(i).getAsJsonObject();
	    		if (!group.has(""clientRefId"")) continue;
	    		if (tenantCode.equals(group.get(""clientRefId"").getAsString())) return group.get(""ipOrg"").getAsInt();
	    }
	   
	   System.out.println(""Tenant could not be found for code:"" + tenantCode);
	   System.exit(-1);
	
	   return null;
   }
  
  
   /*
    *  This function generates an access token for a user that will grant them access to
    *  call REST API endpoints.
    */
  
   public static String generateToken(String host, String username, String password) throws IOException {
   	
   	  	Content c = Request.post(host + ""/api/refresh-tokens"")
 	    		.addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
 	    		.addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
 	    		.addHeader(""Content-Type"", ""application/json"")
 	    		.bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
 	        .execute().returnContent();
 	    	
 	    JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
 	    JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");
 	   
 	    if (accessToken!=null) {
 	    		System.out.println(""Access Token: "" + accessToken);
 	    } else {
 	    		System.out.println(""Token not retrieved successfully"");
 	    		System.exit(-1);
 	    }
 	    return accessToken.getAsString();
   	
   } 
}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class ListUserAccessToClientOrg
    {
        static async Task Main(string[] args)
        {
            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";
            string tenantClientReferenceId = ""NEWCLIENT"";

            string token = await GenerateToken(host, restUsername, restPassword);

            int tenantId = await RetrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);
            Console.WriteLine(""Tenant Id: "" + tenantId);

            using (var httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                HttpResponseMessage response = await httpClient.GetAsync($""{host}/api/orgs/{tenantId}/user-access"");

                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    JArray users = (JArray)jsonObject[""items""];

                    Console.WriteLine($""{users.Count} user(s) have access to tenant {tenantClientReferenceId}"");

                    foreach (JObject user in users)
                    {
                        Console.WriteLine($""User {user[""userId""].Value<int>()}: {user[""name""].Value<string>()}"");
                    }
                }
                else
                {
                    Console.WriteLine($""Failed to retrieve user access. Status code: {response.StatusCode}"");
                }
            }
        }

        static async Task<int> RetrieveTenantIpIdForTenantName(string host, string token, string tenantCode)
        {
            using (var httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                HttpResponseMessage response = await httpClient.GetAsync($""{host}/api/orgs"");

                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    JArray groups = (JArray)jsonObject[""items""];

                    foreach (JObject group in groups)
                    {
                        if (group[""clientRefId""] != null && tenantCode.Equals(group[""clientRefId""].Value<string>()))
                        {
                            return group[""ipOrg""].Value<int>();
                        }
                    }
                }
                else
                {
                    Console.WriteLine($""Failed to retrieve tenant ID. Status code: {response.StatusCode}"");
                }

                Console.WriteLine($""Tenant could not be found for code: {tenantCode}"");
                Environment.Exit(-1);
                return 0; // Dummy return to satisfy method signature
            }
        }

        static async Task<string> GenerateToken(string host, string username, string password)
        {
            using (var httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                
                var requestBody = new
                {
                    userName = username,
                    password = password
                };
                
                var jsonRequest = JsonConvert.SerializeObject(requestBody);
                var content = new StringContent(jsonRequest);
                content.Headers.ContentType = new MediaTypeHeaderValue(""application/json"");
                
                HttpResponseMessage response = await httpClient.PostAsync($""{host}/api/refresh-tokens"", content);

                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].Value<string>();

                    if (!string.IsNullOrEmpty(accessToken))
                    {
                        Console.WriteLine(""Access Token: "" + accessToken);
                        return accessToken;
                    }
                    else
                    {
                        Console.WriteLine(""Token not retrieved successfully"");
                        Environment.Exit(-1);
                        return null; // Dummy return to satisfy method signature
                    }
                }
                else
                {
                    Console.WriteLine($""Failed to generate token. Status code: {response.StatusCode}"");
                    Environment.Exit(-1);
                    return null; // Dummy return to satisfy method signature
                }
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""
	tenantClientReferenceId := ""NEWCLIENT""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	tenantId, err := retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId)
	if err != nil {
		fmt.Println(""Error retrieving tenant ID:"", err)
		return
	}
	fmt.Println(""Tenant ID:"", tenantId)

	client := &http.Client{}
	req, err := http.NewRequest(""GET"", fmt.Sprintf(""%s/api/orgs/%d/user-access"", host, tenantId), nil)
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	var response map[string]interface{}
	err = json.Unmarshal(body, &response)
	if err != nil {
		fmt.Println(""Error parsing JSON:"", err)
		return
	}

	userList := response[""items""].([]interface{})
	fmt.Printf(""%d user(s) have access to tenant %s\n"", len(userList), tenantClientReferenceId)

	for _, u := range userList {
		user := u.(map[string]interface{})
		fmt.Printf(""User %d: %s\n"", int(user[""userId""].(float64)), user[""name""].(string))
	}
}

func generateToken(host, username, password string) (string, error) {
	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": username,
		""password"": password,
	})
	if err != nil {
		return """", err
	}

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		return """", err
	}

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return """", err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return """", err
	}

	var response map[string]interface{}
	err = json.Unmarshal(body, &response)
	if err != nil {
		return """", err
	}

	accessToken := response[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if accessToken == """" {
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	return accessToken, nil
}

func retrieveTenantIpIdForTenantName(host, token, tenantCode string) (int, error) {
	nonce := rand.Int63()

	client := &http.Client{}
	req, err := http.NewRequest(""GET"", host+""/api/orgs"", nil)
	if err != nil {
		return 0, err
	}

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, err
	}

	var response map[string]interface{}
	err = json.Unmarshal(body, &response)
	if err != nil {
		return 0, err
	}

	groups := response[""items""].([]interface{})
	for _, g := range groups {
		group := g.(map[string]interface{})

		if group[""clientRefId""] != nil {
			if group[""clientRefId""].(string) == tenantCode {
				return int(group[""ipOrg""].(float64)), nil
			}
		}
	}

	return 0, fmt.Errorf(""Tenant could not be found for code: %s"", tenantCode)
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const tenantClientReferenceId = ""NEWCLIENT"";

    try {
        const token = await generateToken(host, restUsername, restPassword);
        if (!token) {
            console.error(""Failed to retrieve access token"");
            return;
        }

        console.log(""Token:"", token);

        const tenantId = await retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);
        console.log(""Tenant Id:"", tenantId);

        const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
        const headers = {
            'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
            'Accept': 'application/vnd.yellowfin.api-v1+json',
            'Content-Type': 'application/json'
        };

        const response = await fetch(`${host}/api/orgs/${tenantId}/user-access`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.json();
        const users = responseBody.items;

        console.log(`${users.length} user(s) have access to tenant ${tenantClientReferenceId}`);

        users.forEach(user => {
            console.log(`User ${user.userId}: ${user.name}`);
        });

    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function retrieveTenantIpIdForTenantName(host, token, tenantCode) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/orgs`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.json();
        const groups = responseBody.items;

        for (let i = 0; i < groups.length; i++) {
            const group = groups[i];
            if (group.clientRefId && group.clientRefId === tenantCode) {
                return group.ipOrg;
            }
        }

        console.log(`Tenant could not be found for code: ${tenantCode}`);
        process.exit(-1);

    } catch (error) {
        console.error(""Error:"", error.message);
        throw error;
    }
}

async function generateToken(host, username, password) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: username,
        password: password
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.json();
        const accessToken = responseBody._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
            return accessToken;
        } else {
            console.log(""Token not retrieved"");
        }

    } catch (error) {
        console.error(""Error:"", error.message);
        throw error;
    }

    return null;
}

main();
PHP
<?php

function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    echo ""Token: "" . $token . ""\n"";

    $tenantClientReferenceId = ""NEWCLIENT"";

    try {
        $tenantId = retrieveTenantIpIdForTenantName($host, $token, $tenantClientReferenceId);
        echo ""Tenant Id: "" . $tenantId . ""\n"";

        $nonce = mt_rand();
        $headers = array(
            'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
            'Accept: application/vnd.yellowfin.api-v1+json',
            'Content-Type: application/json'
        );

        $response = httpRequest('GET', ""$host/api/orgs/$tenantId/user-access"", $headers);

        $jsonObject = json_decode($response);
        $userList = $jsonObject->items;
        $users = $userList;

        echo count($users) . "" user(s) have access to tenant "" . $tenantClientReferenceId . ""\n"";

        foreach ($users as $user) {
            echo ""User "" . $user->userId . "": "" . $user->name . ""\n"";
        }

    } catch (Exception $e) {
        echo ""Error: "" . $e->getMessage();
    }
}

function retrieveTenantIpIdForTenantName($host, $token, $tenantCode) {
    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', ""$host/api/orgs"", $headers);

    $jsonObject = json_decode($response);
    $groupList = $jsonObject->items;
    $groups = $groupList;

    foreach ($groups as $group) {
        if (isset($group->clientRefId) && $group->clientRefId == $tenantCode) {
            return $group->ipOrg;
        }
    }

    echo ""Tenant could not be found for code:"" . $tenantCode . ""\n"";
    exit(-1);
}

function generateToken($host, $restUsername, $restPassword) {
    $nonce = mt_rand();

    $requestBody = json_encode(array(
        ""userName"" => $restUsername,
        ""password"" => $restPassword
    ));

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);

    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken . ""\n"";
        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($method === 'POST' && $data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Python
import json
import random
import time
import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""
    tenant_client_reference_id = ""NEWCLIENT""

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    print(""Token:"", token)

    try:
        tenant_id = retrieve_tenant_ip_id_for_tenant_name(host, token, tenant_client_reference_id)
        print(""Tenant Id:"", tenant_id)

        nonce = random.randint(0, 2**63 - 1)
        headers = {
            'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)} , nonce={nonce}, token={token}',
            'Accept': 'application/vnd.yellowfin.api-v1+json',
            'Content-Type': 'application/json'
        }

        response = requests.get(f""{host}/api/orgs/{tenant_id}/user-access"", headers=headers)
        response.raise_for_status()

        json_response = response.json()
        user_list = json_response.get(""items"", [])

        print(f""{len(user_list)} user(s) have access to tenant {tenant_client_reference_id}"")

        for user in user_list:
            print(f""User {user.get('userId')}: {user.get('name')}"")

    except requests.RequestException as e:
        print(f""Error sending request: {e}"")
    except Exception as e:
        print(f""Error: {e}"")


def retrieve_tenant_ip_id_for_tenant_name(host, token, tenant_code):
    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.get(f""{host}/api/orgs"", headers=headers)
    response.raise_for_status()

    json_response = response.json()
    groups = json_response.get(""items"", [])

    for group in groups:
        if ""clientRefId"" in group and group[""clientRefId""] == tenant_code:
            return group[""ipOrg""]

    raise Exception(f""Tenant could not be found for code: {tenant_code}"")


def generate_token(host, username, password):
    nonce = random.randint(0, 2**63 - 1)

    request_body = json.dumps({
        ""userName"": username,
        ""password"": password
    })

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.post(f""{host}/api/refresh-tokens"", headers=headers, data=request_body)
    response.raise_for_status()

    json_response = response.json()
    access_token = json_response[""_embedded""][""accessToken""][""securityToken""]

    if access_token:
        print(f""Access Token: {access_token}"")
        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")


if __name__ == ""__main__"":
    main()

Delete a Tenant

Deleting a tenant can be achieved with the DELETE /api/orgs/{tenantId} end-point Delete Org, where tenantId is the integer identifier for the tenant / client organization.

The following code examples delete a specific client organization (identified by its clientOrgRef code).

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Delete a Client Org using the Yellowfin REST API
 */
public class DeleteClientOrg {
    public static void main(String[] args) throws Exception {

        System.out.print(""Delete a Tenant"");

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String tenantClientReferenceId = ""NEWCLIENT"";

        String token = generateToken(host, restUsername, restPassword);

        Integer tenantId = retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);

        System.out.println(""Tenant Id: "" + tenantId);

        Content c = Request.delete(host + ""/api/orgs/"" + tenantId)
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        System.out.print(c.asString());

    }

    /*
     *  This function fetches a client organization's integer id for a given clientRefCode
     */

    public static Integer retrieveTenantIpIdForTenantName(String host, String token, String tenantCode) throws IOException {

        Content c = Request.get(host + ""/api/orgs"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement groupList = jsonObject.get(""items"");
        JsonArray groups = groupList.getAsJsonArray();

        for (int i=0; i < groups.size(); i++ ) {
            JsonObject group = groups.getAsJsonArray().get(i).getAsJsonObject();
            if (!group.has(""clientRefId"")) continue;
            if (tenantCode.equals(group.get(""clientRefId"").getAsString())) return group.get(""ipOrg"").getAsInt();
        }

        System.out.println(""Tenant could not be found for code:"" + tenantCode);
        System.exit(-1);

        return null;
    }


    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class DeleteClientOrg
    {
        static async Task Main(string[] args)
        {
            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";
            string tenantClientReferenceId = ""NEWCLIENT"";

            string token = await GenerateToken(host, restUsername, restPassword);

            int tenantId = await RetrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);
            Console.WriteLine(""Tenant Id: "" + tenantId);

            using (var httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.DeleteAsync($""{host}/api/orgs/{tenantId}"");

                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine($""Failed to delete client org. Status code: {response.StatusCode}"");
                }
            }
        }

        static async Task<int> RetrieveTenantIpIdForTenantName(string host, string token, string tenantCode)
        {
            using (var httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.GetAsync($""{host}/api/orgs"");

                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    JArray groups = (JArray)jsonObject[""items""];

                    foreach (JObject group in groups)
                    {
                        if (group[""clientRefId""] != null && tenantCode.Equals(group[""clientRefId""].Value<string>()))
                        {
                            return group[""ipOrg""].Value<int>();
                        }
                    }
                }
                else
                {
                    Console.WriteLine($""Failed to retrieve tenant ID. Status code: {response.StatusCode}"");
                }

                Console.WriteLine($""Tenant could not be found for code: {tenantCode}"");
                Environment.Exit(-1);
                return 0; // Dummy return to satisfy method signature
            }
        }

        static async Task<string> GenerateToken(string host, string username, string password)
        {
            using (var httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                var requestBody = new
                {
                    userName = username,
                    password = password
                };

                var jsonRequest = JsonConvert.SerializeObject(requestBody);
                var content = new StringContent(jsonRequest);
                content.Headers.ContentType = new MediaTypeHeaderValue(""application/json"");

                HttpResponseMessage response = await httpClient.PostAsync($""{host}/api/refresh-tokens"", content);

                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].Value<string>();

                    if (!string.IsNullOrEmpty(accessToken))
                    {
                        Console.WriteLine(""Access Token: "" + accessToken);
                    }
                    else
                    {
                        Console.WriteLine(""Token not retrieved"");
                        Environment.Exit(-1);
                    }

                    return accessToken;
                }
                else
                {
                    Console.WriteLine($""Failed to generate token. Status code: {response.StatusCode}"");
                    Environment.Exit(-1);
                    return null; // Dummy return to satisfy method signature
                }
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""
	tenantClientReferenceId := ""NEWCLIENT""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	tenantId, err := retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId)
	if err != nil {
		fmt.Println(""Error retrieving tenant ID:"", err)
		return
	}

	fmt.Println(""Tenant Id:"", tenantId)

	client := &http.Client{}
	req, err := http.NewRequest(""DELETE"", fmt.Sprintf(""%s/api/orgs/%d"", host, tenantId), nil)
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	fmt.Println(string(body))
}

func retrieveTenantIpIdForTenantName(host, token, tenantCode string) (int, error) {
	client := &http.Client{}
	req, err := http.NewRequest(""GET"", fmt.Sprintf(""%s/api/orgs"", host), nil)
	if err != nil {
		return 0, fmt.Errorf(""error creating request: %v"", err)
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, fmt.Errorf(""error sending request: %v"", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, fmt.Errorf(""error reading response body: %v"", err)
	}

	var jsonResponse map[string]interface{}
	if err := json.Unmarshal(body, &jsonResponse); err != nil {
		return 0, fmt.Errorf(""error parsing JSON response: %v"", err)
	}

	groups := jsonResponse[""items""].([]interface{})
	for _, group := range groups {
		groupObj := group.(map[string]interface{})
		if clientRefId, ok := groupObj[""clientRefId""].(string); ok && clientRefId == tenantCode {
			ipOrg := int(groupObj[""ipOrg""].(float64))
			return ipOrg, nil
		}
	}

	return 0, fmt.Errorf(""tenant could not be found for code: %s"", tenantCode)
}

func generateToken(host, username, password string) (string, error) {
	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": username,
		""password"": password,
	})
	if err != nil {
		return """", fmt.Errorf(""error marshaling request body: %v"", err)
	}

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", fmt.Sprintf(""%s/api/refresh-tokens"", host), bytes.NewBuffer(requestBody))
	if err != nil {
		return """", fmt.Errorf(""error creating request: %v"", err)
	}

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return """", fmt.Errorf(""error sending request: %v"", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return """", fmt.Errorf(""error reading response body: %v"", err)
	}

	var jsonResponse map[string]interface{}
	if err := json.Unmarshal(body, &jsonResponse); err != nil {
		return """", fmt.Errorf(""error parsing JSON response: %v"", err)
	}

	accessToken := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if accessToken == """" {
		return """", fmt.Errorf(""token not retrieved successfully"")
	}

	fmt.Println(""Access Token:"", accessToken)
	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";
    const tenantClientReferenceId = ""NEWCLIENT"";

    try {
        const token = await generateToken(host, restUsername, restPassword);

        if (!token) {
            console.error(""Failed to retrieve access token"");
            return;
        }

        const tenantId = await retrieveTenantIpIdForTenantName(host, token, tenantClientReferenceId);
        console.log(""Tenant Id:"", tenantId);

        const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

        const headers = {
            'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
            'Accept': 'application/vnd.yellowfin.api-v1+json',
            'Content-Type': 'application/json'
        };

        const response = await fetch(`${host}/api/orgs/${tenantId}`, {
            method: 'DELETE',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        console.log(responseBody);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function retrieveTenantIpIdForTenantName(host, token, tenantCode) {
    try {
        const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

        const headers = {
            'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
            'Accept': 'application/vnd.yellowfin.api-v1+json',
            'Content-Type': 'application/json'
        };

        const response = await fetch(`${host}/api/orgs`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const groups = jsonResponse.items;

        for (let i = 0; i < groups.length; i++) {
            const group = groups[i];
            if (group.clientRefId && group.clientRefId === tenantCode) {
                return group.ipOrg;
            }
        }

        console.error(""Tenant could not be found for code:"", tenantCode);
        process.exit(-1);
    } catch (error) {
        console.error(""Error:"", error.message);
        throw error;
    }
}

async function generateToken(host, username, password) {
    try {
        const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

        const headers = {
            'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
            'Accept': 'application/vnd.yellowfin.api-v1+json',
            'Content-Type': 'application/json'
        };

        const body = JSON.stringify({ userName: username, password: password });

        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(""Access Token:"", accessToken);
            return accessToken;
        } else {
            console.error(""Token not retrieved successfully"");
            process.exit(-1);
        }
    } catch (error) {
        console.error(""Error:"", error.message);
        throw error;
    }
}

main();
PHP
<?php
function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";
    $tenantClientReferenceId = ""NEWCLIENT"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    echo ""Delete a Tenant\n"";
    echo ""Tenant Client Reference Id: "" . $tenantClientReferenceId . ""\n"";

    try {
        $tenantId = retrieveTenantIpIdForTenantName($host, $token, $tenantClientReferenceId);
    } catch (Exception $e) {
        echo ""Error retrieving Tenant Id: "" . $e->getMessage();
        return;
    }

    echo ""Tenant Id: "" . $tenantId . ""\n"";

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('DELETE', ""$host/api/orgs/$tenantId"", $headers);
        echo $response;
    } catch (Exception $e) {
        echo ""Error deleting client org: "" . $e->getMessage();
    }
}

function retrieveTenantIpIdForTenantName($host, $token, $tenantCode) {
    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', ""$host/api/orgs"", $headers);

    $jsonResponse = json_decode($response, true);
    if (isset($jsonResponse[""items""])) {
        $groups = $jsonResponse[""items""];
        foreach ($groups as $group) {
            if (isset($group[""clientRefId""]) && $group[""clientRefId""] === $tenantCode) {
                return $group[""ipOrg""];
            }
        }
    }

    throw new Exception(""Tenant could not be found for code: $tenantCode"");
}

function generateToken($host, $username, $password) {
    $nonce = mt_rand();
    $requestBody = json_encode(array(
        ""userName"" => $username,
        ""password"" => $password
    ));

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);
    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken;
        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);
    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);
    return $response;
}

main();
?>
Python
import json
import random
import time
import requests


def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""
    tenant_client_reference_id = ""NEWCLIENT""

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    print(""Delete a Tenant"")
    print(f""Tenant Client Reference Id: {tenant_client_reference_id}"")

    try:
        tenant_id = retrieve_tenant_ip_id_for_tenant_name(host, token, tenant_client_reference_id)
    except Exception as e:
        print(f""Error retrieving Tenant Id: {e}"")
        return

    print(f""Tenant Id: {tenant_id}"")

    nonce = random.randint(0, 2 ** 63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.delete(f""{host}/api/orgs/{tenant_id}"", headers=headers)
        response.raise_for_status()
        print(response.text)
    except requests.RequestException as e:
        print(f""Error deleting client org: {e}"")


def retrieve_tenant_ip_id_for_tenant_name(host, token, tenant_code):
    nonce = random.randint(0, 2 ** 63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.get(f""{host}/api/orgs"", headers=headers)
        response.raise_for_status()
        json_response = response.json()

        for group in json_response.get(""items"", []):
            if ""clientRefId"" in group and group[""clientRefId""] == tenant_code:
                return group[""ipOrg""]

        raise Exception(f""Tenant could not be found for code: {tenant_code}"")

    except requests.RequestException as e:
        raise Exception(f""Error retrieving tenant IP Id: {e}"")


def generate_token(host, username, password):
    nonce = random.randint(0, 2 ** 63 - 1)

    # Create request body
    request_body = json.dumps({
        ""userName"": username,
        ""password"": password
    })

    # Create request headers
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    # Send HTTP request
    try:
        response = requests.post(f""{host}/api/refresh-tokens"", headers=headers, data=request_body)
        response.raise_for_status()
        json_response = response.json()
        access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
        print(""Access Token:"", access_token)
        return access_token

    except requests.RequestException as e:
        raise Exception(f""Error generating token: {e}"")


if __name__ == ""__main__"":
    main()

Custom Styling a Tenant

When creating a Client Organization a custom styling folder can be specified. The specified client folder can be created inside the Yellowfin/appserver/webapps/ROOT/customcss directory. Any stylesheets created in this directory will be applied to the Client Organization. 

The custom folder name can be assigned manually through the administration interface or specified via the model when administering the Client via the REST API.

Any styles defined in the stylesheet directory will override the default Yellowfin styles. For example this CSS overrides some of the default CSS variables:

When logging into the associated client organization the overridden styles are applied:


  • No labels