Planning Analytics

 View Only

 How to execute a POST Request using ExecuteHttpRequest in a TI Process?

Erwan Tang's profile image
Erwan Tang posted Wed September 24, 2025 12:27 PM

Hello everyone,

I’m currently trying to execute a POST request from a TI process in Planning Analytics using ExecuteHttpRequest, but I keep running into issues. I’d appreciate some help or guidance from anyone who has managed to get this working.

Here’s what I’ve done so far:

  • I wrote a TI process that tries to authenticate against IBM Cloud and then call the PA REST API.

  • I’m able to get an access_token from the IBM Cloud IAM endpoint by using my API key. That part seems to work fine.

  • However, when I try to use this bearer token to send further requests (for example, creating a folder in the PA Contents), I always get a 401 response code.

Here’s a simplified version of the code I’m running in the TI process:

(It's a version I adapted from Stuart King process you can find here: PASaaSReplication/processes/Replicate data.ti at main · StuartStephenKing/PASaaSReplication)

GitHub remove preview
PASaaSReplication/processes/Replicate data.ti at main · StuartStephenKing/PASaaSReplication
Contribute to StuartStephenKing/PASaaSReplication development by creating an account on GitHub.
View this on GitHub >

 

# Request Access Token vGrant_type = 'urn:ibm:params:oauth:grant-type:apikey'; vTokenUrl = 'https://iam.cloud.ibm.com/identity/token?apikey=' | vAPIKey | '&grant_type=' | vGrant_type; ExecuteHttpRequest('POST', vTokenUrl); responseCode = HttpResponseGetStatusCode(); vResponseBody = HttpResponseGetBody(); ASCIIOUTPUT(vLogFile, vResponseBody); # Extract bearer token from response
ExecuteHttpRequest( 'POST', vTokenUrl );
responseCode = HttpResponseGetStatusCode();
vResponseBody  = HttpResponseGetBody();
ASCIIOUTPUT( vLogFile, vResponseBody );
vResponseBodyLength = LONG ( vResponseBody );
vAccessTokenStr = '"access_token":"';
vAccessTokenStart = SCAN( vAccessTokenStr, vResponseBody );
vAccessTokenLength = LONG( vAccessTokenStr );
vResponseBodyAccessTokenStrToEnd= SUBST( vResponseBody, vAccessTokenStart + vAccessTokenLength, vResponseBodyLength - vAccessTokenStart);
vAccessTokenEnd = SCAN( '"', vResponseBodyAccessTokenStrToEnd ) - 1;
vBearerToken = SUBST( vResponseBodyAccessTokenStrToEnd, 1, vAccessTokenEnd );
ASCIIOUTPUT( vLogFile, 'accessToken: ' | vBearerToken ); # Try to call PA API vUrl = P_S_SERVER_URL_SOURCE | '/api/' | P_S_TENANT_ID_TARGET | '/v0/tm1/' | P_S_SERVER_NAME_TARGET | '/api/v1/Contents(...)/Contents'; vJSONCommand = '{"@odata.type": "#ibm.tm1.api.v1.Folder", "Name": "TestFolder1"}'; sHeaderToken = '-h Authorization: Bearer ' | vBearerToken; ExecuteHttpRequest('POST', vUrl, '-k', sHeaderToken, '-h Content-Type:application/json', '-d ' | vJSONCommand); responseCode = HttpResponseGetStatusCode(); responseBody = HttpResponseGetBody(); ASCIIOUTPUT(vLogFile, 'Response Code: ' | NumberToString(responseCode)); ASCIIOUTPUT(vLogFile, responseBody);

What I’ve observed so far:

  • The access token is generated correctly from IBM Cloud IAM.

  • When using the token in a TI request, I consistently get a 401.

  • If I try the same request using the paSession cookie, it works fine. (I executed the authentication in Postman just to get the paSession cookie)

  • That leads me to believe the issue is not with the TI syntax itself, but rather with how the PAaaS authentication works.

My main questions:

  1. How do I get the correct API key or credentials that give me access to the PAaaS service from a TI process with the right access_token ?

  2. Alternatively, is there a way to programmatically retrieve the paSession cookie from within a TI process, similar to how Postman handles it?

  3. Has anyone successfully used ExecuteHttpRequest('POST', …) in TI against PAaaS, and if so, what authentication flow did you use?

Any advice or concrete examples would be very welcome. I feel like I’m missing a key step regarding authentication between IAM and the PAaaS instance.

Thanks a lot in advance for your help!

Erwan

Edward Stuart's profile image
Edward Stuart IBM Champion

Hi Erwan,

Authentication was via IBM Cloud IAM when v12 was first released but has been replaced by an easier to manage/ authenticate method of obtaining API keys.

See this link for a comprehensive example of working with files within v12 and the authentication method to use:

https://community.ibm.com/community/user/blogs/jessica-nicholls/2025/02/03/managing-paaas-with-apis

Hope this helps and let us know how you get on,

Edd

Erwan Tang's profile image
Erwan Tang

Hi Edward, 

Thank you for your answer.

I actually already went through the link you shared with me, which covers how to execute HTTP request from PostMan, but I am actually trying to execute it directly within PAaaS TI process.

After discussing with IBM Support, encoding the API key using the Base64Encode function allowed the POST request to execute successfully.

vNow     = TIMST (NOW(), '\Y\m\d\h\i\s' );
vLogFile = '/Logs/Processes/pull_data_from_remote_cubes_' | vNow | '.log';
vUser = TM1User;
vAPIKey = ATTRS('}Clients', vUser, 'PASaaS API Key');

# Construct URL
vBaseURL = 'https://eu-central-1.planninganalytics.saas.ibm.com';
vTenantID = '';   #TO BE CHANGED
vUrl = vBaseURL | '/api/' | vTenantID | '/v0/rolemgmt/v1/users/me';
ASCIIOUTPUT( vLogFile, 'accessToken: ' | vBaseURL );

# Prepare Basic Auth header
vAuthHeader = 'Authorization: Basic ' | Base64Encode('apikey:' | vAPIKey);

# Make request
ExecuteHttpRequest('GET', vUrl, '-k', '-h ' | vAuthHeader, '-h Content-Type:application/json');

# Log output
ASCIIOUTPUT(vLogFile, 'Request URL: ' | vUrl);
responseCode = HttpResponseGetStatusCode();
ASCIIOUTPUT(vLogFile, 'Response Code: ' | NumberToString(responseCode));
responseBody = HttpResponseGetBody();
ASCIIOUTPUT(vLogFile, responseBody);

# Example of POST Request (create folder)
vRemoteDatabase = '';   #TO BE CHANGED
vUrl = vBaseURL | '/api/' | vTenantID | '/v0/tm1/' | vRemoteDatabase | '/api/v1/Contents(' | vQu | 'Files' | vQu | ')/Contents';
vJSONCommand = '{"@odata.type": "#ibm.tm1.api.v1.Folder",    "Name": "TestFolder"}';
ExecuteHttpRequest( 'POST', vUrl,  '-k', '-h Content-Type:application/json', '-d ' | vJSONCommand);

ASCIIOUTPUT(vLogFile, 'TM1 Config Request URL: ' | vUrl );
responseCode = HttpResponseGetStatusCode();
ASCIIOUTPUT(vLogFile, 'TM1 Config Response Code: ' | NumberToString(responseCode));

Thanks again for your help!

Erwan