invalid user in api call | XM Community
Solved

invalid user in api call

  • 15 April 2024
  • 3 replies
  • 47 views

Badge +2

Hello, I receive an error while calling the api via the webservice in a survey workflow and also by using an external python script: {"errorMessage":"invalid_client","errorCode":"AUTH_6.0"}

I have set the api token as authentication. Any idea what causes the error? Is it possible that I can create an api token, but have no permission to use it?

This is the python script (not incl. my ids and token):

 

import requests

def copy_survey(api_token, data_center, owner_id, template_id):
    # Construct the URL
    url = f'https://{data_center}.qualtrics.com/API/v3/survey-definitions'
    
    # Headers for the request
    headers = {
        'Authorization': f'Bearer {api_token}',
        'Content-Type': 'application/json'
    }
    
    # Data (payload) of the POST request
    data = {
        "SurveyName": "Copied Survey",
        "SurveyDescription": "This is a survey copied from a template.",
        "ProjectCategory": "Academic",
        "SurveyOwnerID": owner_id,
        "SurveyTemplateID": template_id
    }
    
    # Make the POST request
    response = requests.post(url, json=data, headers=headers)
    
    # Check if the request was successful
    if response.status_code == 200:
        print("Survey copied successfully!")
        return response.json()  # Return the JSON response from the API
    else:
        print("Failed to copy the survey. Status code:", response.status_code)
        return response.text  # Return the error response if not successful

# Replace the following variables with your actual data
API_TOKEN = 'your_api_token_here'
DATA_CENTER = 'your_data_center_id_here'  # e.g., 'ca1', 'eu', 'us', etc.
OWNER_ID = 'your_qualtrics_user_id'
TEMPLATE_ID = 'template_survey_id_to_copy'

# Call the function to copy the survey
response_data = copy_survey(API_TOKEN, DATA_CENTER, OWNER_ID, TEMPLATE_ID)
print(response_data)

 

icon

Best answer by carolsuehaney 17 April 2024, 00:41

View original

3 replies

Badge +3

Hello -

Using the API, I am not aware of a way to reference a template_id.  That said, here is how I copy a survey (not its data, its actual design structure).  

First, I get an existing survey (get_survey) and then write the resultant qsf down to a temp file.

Second, I import the qsf into a new survey.

Best, 

Carol

##################

import requests
import json


def get_survey(api_token, data_center, owner_id, survey_id):
    baseUrl = "https://{0}.qualtrics.com/API/v3/survey-definitions/{1}?format=qsf".format(data_center, survey_id)

    headers = {
        "Content-Type": "application/json",
        "X-API-TOKEN": api_token
    }

    response = requests.request("GET", baseUrl, headers=headers)

    jsonResponse = json.loads(response.text)    # convert the text JSON to a JSON object

    print("export status: ",jsonResponse['meta']['httpStatus'])

    return jsonResponse

    
def import_survey(api_token, data_center, survey_name, qsf):
    baseUrl = "https://{0}.qualtrics.com/API/v3/surveys".format(data_center)

    headers = {
        "x-api-token": api_token
        }

    files = {
        'file': (qsf, open(qsf, 'rb'), 'application/vnd.qualtrics.survey.qsf')
      }

    data = { "name": survey_name }
    response = requests.post(baseUrl, files=files, data=data, headers=headers)
    return response.text

API_TOKEN = 'TOKEN' # in your account settings
DATA_CENTER = 'iad1'  # e.g., 'ca1', 'eu', 'us', etc.
OWNER_ID = 'UR_000000000000'. # in your account settings
SURVEY_ID = 'SV_0000000000000' # the survey you want to copy FROM
NEW_SURVEY_NAME = "Example_0416" # the name of the new survey
SURVEY_QSF = "temp_survey.qsf"  # just a temp file to hold the exported survey json (qsf)
LANG = "EN"
PLATFORM = "CORE"

qsf_data = get_survey(API_TOKEN, DATA_CENTER, OWNER_ID, SURVEY_ID)

with open(SURVEY_QSF, 'w') as jsonFile:
    jsonFile.write(json.dumps(qsf_data["result"], indent=2))

import_data = import_survey(API_TOKEN, DATA_CENTER, NEW_SURVEY_NAME, SURVEY_QSF)
 

Badge +2

Thanks. Indeed it works only via qsf file. But my api is still not running. Need to check if there are company restrictions.

Badge +2

thanks again, it worked. There was one dot in your code, creating an error. I adjusted the code with some error handling and took out some stuff:

 

##<<
 

import requests
import json

def get_survey(api_token, data_center, survey_id):
    # Build the URL for retrieving a survey definition
    base_url = f"https://{data_center}.qualtrics.com/API/v3/surveys/{survey_id}"
    headers = {
        "Content-Type": "application/json",
        "X-API-TOKEN": api_token
    }
    # Make the GET request
    response = requests.get(base_url, headers=headers)
    print(f"GET Survey Response: {response.text}")  # Detailed logging of the API response
    if response.status_code == 200:
        json_response = json.loads(response.text)
        print("Export status: ", json_response.get('meta', {}).get('httpStatus', 'Unknown status'))
        return json_response
    else:
        print(f"Error fetching survey: HTTP {response.status_code}")
        return None

def import_survey(api_token, data_center, survey_name, qsf):
    # Build the URL for creating a new survey
    base_url = f"https://{data_center}.qualtrics.com/API/v3/surveys"
    headers = {"X-API-TOKEN": api_token}
    # Prepare the file and data for the POST request
    with open(qsf, 'rb') as file:
        files = {'file': (qsf, file, 'application/vnd.qualtrics.survey.qsf')}
        data = {"name": survey_name}
        response = requests.post(base_url, files=files, data=data, headers=headers)
        print(f"POST Survey Response: {response.text}")  # Detailed logging of the API response
        return response.text

# Define your API token, data center, and survey details
API_TOKEN = '00000000000'  # Ensure this token is correct
DATA_CENTER = ‘000'  # Verify this is correct for your account
SURVEY_ID = 'SV_000000000000'
NEW_SURVEY_NAME = "Example_0416"
SURVEY_QSF = "temp_survey.qsf"

# Execute the get survey function and handle the response
qsf_data = get_survey(API_TOKEN, DATA_CENTER, SURVEY_ID)
if qsf_data and 'result' in qsf_data:
    # Save the survey definition to a file
    with open(SURVEY_QSF, 'w') as json_file:
        json_file.write(json.dumps(qsf_data['result'], indent=2))
    # Import the survey with the saved definition
    import_data = import_survey(API_TOKEN, DATA_CENTER, NEW_SURVEY_NAME, SURVEY_QSF)
    print("Import response: ", import_data)
else:
    print("Failed to get the survey data or 'result' key missing.")

Leave a Reply