Expand my Community achievements bar.

Get ready! An upgraded Experience League Community experience is coming in January.

GRM internal server error when trying to use JWT Auth and Adobe Analytics API

Avatar

Level 1

Howdy,

 

I'm trying to connect to Adobe to run some prebaked queries on a schedule to return for my relational database.

 

When I code up my python script though, I keep getting a combination of errors depending on the time I run my script.  One time it can return this...

Error retrieving report data:
{"error_code":"500701", "message":"GRM internal server error"}

 

Other times it will return this; I am not making changes to my script between runs...

Error retrieving report data:
{"error_code":"403025", "message":"Profile is not valid"}

 

 

import sys
import csv
import json
import time
import requests
import jwt

# Set up your API credentials and report suite ID
client_id = 'helloWorld!'
client_secret = 'shhhhhhhhhhh'
technical_account_id = 'stuffandthings@techacct.adobe.com'
org_id = 'thingsandstuff@AdobeOrg'
private_key = 'private.key'
report_suite_id = 'honeybadger'
json_query = 'marketing_channels.json'

# Set up the API endpoint and authentication URL
auth_url = 'https://ims-na1.adobelogin.com/ims/exchange/jwt/'
aud_url = f'https://ims-na1.adobelogin.com/c/{client_id}'
api_url = f'https://analytics.adobe.io/api/{report_suite_id}/reports'

# Load your private key
with open(private_key, 'r') as f:
    private_key_data = f.read()

# Set up the JWT payload
jwt_payload = {
    'iss': org_id,
    'sub': technical_account_id,
    'aud': 'https://ims-na1.adobelogin.com/c/' + client_id,
    'exp': int(time.time()) + 300,
    'iat': int(time.time()),
    'https://ims-na1.adobelogin.com/s/ent_analytics_bulk_ingest_sdk': True,
    'meta_scopes': ['ent_analytics_bulk_ingest_sdk','read','write','https://analytics.adobe.io/api/honeybadger/write','https://analytics.adobe.io/api/honeybadger/read']
}

# Generate the JWT token
jwt_token = jwt.encode(jwt_payload, private_key_data, algorithm='RS256')

# Exchange the JWT token for an access token
auth_headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Cache-Control': 'no-cache'
}
auth_payload = {
    'client_id': client_id,
    'client_secret': client_secret,
    'jwt_token': jwt_token
}
auth_response = requests.post(auth_url, headers=auth_headers, data=auth_payload)

if auth_response.status_code == 200:
    access_token = auth_response.json()['access_token']
    print("Access Token is: " + access_token)
else:
    print('Error exchanging JWT token for access token:')
    print(auth_response.text)
    sys.exit()

# Load your query JSON
with open(json_query, 'r') as f:
    query = json.load(f)

# Make the API call
headers = {
    'Authorization': f'Bearer {access_token}',
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'x-api-key': client_id,
    'x-proxy-global-company-id': org_id
}
response = requests.post(api_url, headers=headers, json=query)

# Process the response data
if response.status_code == 200:
    data = response.json()
    
    # Write data to CSV file
    with open('report_data.csv', 'w', newline='') as csvfile:
        writer = csv.writer(csvfile)
        
        # Write headers
        headers = [col['id'] for col in data['columns']]
        writer.writerow(headers)
        
        # Write rows
        for row in data['rows']:
            writer.writerow(row)
            
    print('Data successfully written to report_data.csv')
else:
    print('Error retrieving report data:')
    print(response.text)
    sys.exit()

 

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

7 Replies

Avatar

Level 1

Hi @ChipPrj-3!

Have you, by any chance, resolved this problem?

Avatar

Level 1

Sadly no, still banging my head against it

Avatar

Level 1


We are having the same issue at our end. We are trying through a REST client

Avatar

Level 1

Hi there,

I was able to resolve it by using different organisation ID format. OP uses this one:

org_id = 'thingsandstuff@AdobeOrg'

And I've been getting the 'GRM internal server error' when I was using ID in similar format (with @AdobeOrg suffix).

 

I've tried to call the https://analytics.adobe.io/discovery/me endpoint (also with Bearer token and x-api-key) and the response contains a globalCompanyId property. I've tried to use it instead of @AdobeOrg one and I get successful responses.

Avatar

Level 1

Similar to alekseib's response, I was able to get past the terribly vague 'GRM internal server error' by using my globalCompanyId (as found in a call to https://analytics.adobe.io/discovery/me with a properly generated access token) in my request URL.  For example, I was trying to call /reports, and it worked when I properly formatted that url like this: 

 
 
[globalCompanyId] is not org id- for us it's a short alphanumeric string.  I missed that detail in the docs somehow-

 

 

Avatar

Level 3

Hi @benwells and everyone! I'm a little bit confused:
first of all approach to Oauth should be more simple with the server-to-server API call...but....I'm facing with many problems! I received

 

 

{
    "error_code": "500701",
    "message": "GRM internal server error"
}
{
    "errorCode": "invalid_token",
    "errorDescription": "Invalid IMS access token.",
    "errorId": "auth-f0edab3e-e264-4b95-b9cf-5548bc38bf48"
}
{
    "error_code": "403025",
    "message": "Profile is not valid"
}

 

 while trying to add different headers to the ones in the official documentation (https://developer.adobe.com/analytics-apis/docs/2.0/guides/endpoints/reports/ ) :

 

x-proxy-global-company-id
x-gw-ims-org-id

 

 with different values I retrieved from https://analytics.adobe.io/discovery/me such as:

 

   "imsOrgs": [
        {
            "imsOrgId": "**********@AdobeOrg",
            "companies": [
                {
                    "globalCompanyId": "XXXXXXXX",
                    "companyName": "...",
                    "apiRateLimitPolicy": "aa_api_****",
                    "dpc": "***"
                }
            ]
        }

 


Should someone clarify:
1) What value use in report api url?

2) What are the right headers?
 3) Do I miss some product profile to my API conf on console? Here's mine...

mirkomanga_0-1710510500581.png

With the 2024Q1 version of the Reporting API?
Thanks a lot!
Regards

 

Avatar

Level 1

Dear I had the same issue and I found the solution. 

 

The first thing is your api url. Your api url should be 

https://analytics.adobe.io/api/{COMPANYID}/reports

Please refer to the documentation in the Github readme about the Adobe API https://github.com/AdobeDocs/analytics-2.0-apis/blob/master/reporting-guide.md.

You get the [COMPANYID] by making a get request to the url https://analytics.adobe.io/discovery/me

headers = "Accept": "application/json",
"Content-Type": "application/json",
"Authorization": f"Bearer {access_token}",
"x-api-key": [client_id]
The response if successful contains the globalCompanyId which represents the [COMPANYID].
 
You must use that same company id in the header of your report post request. The key "x-proxy-global-company-id" 's value in the header is the company id and not the org_id.
 
Your query might also play a role in the response you get. Please use the query example given in the GitHub readme. I think your query should directly start with the report suite id in the form 'rsid'. It must also contain a globalFilters field and a dimension field. 

Hope this will help. Good luck!