Closed catdomin23 closed 3 months ago
Hello @catdomin23! There are two common issues that cause folks to run into this error.
The base URL you pass to the qualtRics package should either look like
yourdatacenterid.qualtrics.com
or likeyourorganizationid.yourdatacenterid.qualtrics.com
curl --request GET \
--url https://XXX.qualtrics.com/API/v3/whoami \
--header 'x-api-token: YOURLONGAPITOKENHERE'
You would need to use your URL and your API token. Do you see anything in the results like:
Notice: Request proxied. For faster response times, use this host instead:
## put your survey ID here:
fetch_url <- qualtRics::generate_url(query = "fetchsurvey", surveyID = "SV_xxx")
raw_payload <- qualtRics:::create_raw_payload(
label = TRUE,
start_date = NULL,
end_date = NULL,
limit = NULL,
time_zone = NULL,
unanswer_recode = NULL,
unanswer_recode_multi = NULL,
include_display_order = TRUE,
include_questions = NULL,
breakout_sets = NULL
)
res <- qualtRics:::qualtrics_api_request("POST", url = fetch_url, body = raw_payload)
res$meta
#> $requestId
#> [1] "f52b2929-b24a-4c9d-88a6-e7c9d3ff660d"
#>
#> $httpStatus
#> [1] "200 - OK"
Created on 2022-04-04 by the reprex package (v2.0.1)
Dear Julia,
thank you for reply! I'm honoured!
Hello @catdomin23! There are two common issues that cause folks to run into this error.
* The first is not having your base URL set correctly. Notice that [when you register your credentials](https://docs.ropensci.org/qualtRics/#register-your-qualtrics-credentials):
The base URL you pass to the qualtRics package should either look like
yourdatacenterid.qualtrics.com
or likeyourorganizationid.yourdatacenterid.qualtrics.com
qualtRics::qualtrics_api_credentials(api_key = "IUxQ4XmxxxxxxrxC7UzV23ww", base_url = "UR_0xxxxxxxISISO.qualtrics.com",install = TRUE) Hope my base URL is ok.
* The second is Qualtrics proxying your request. Do you see any messages about this? For example, what do you see when you run this at the command line (not in R)?
curl --request GET \ --url https://XXX.qualtrics.com/API/v3/whoami \ --header 'x-api-token: YOURLONGAPITOKENHERE'
You would need to use your URL and your API token. Do you see anything in the results like:
Notice: Request proxied. For faster response times, use this host instead:
**curl --request GET --url https://URxxxISO.qualtrics.com/API/v3/whoami --header 'x-api-token: IUxQ4xxxC7UzV23ww'
{"meta":{"httpStatus":"400 - Bad Request","error":{"errorMessage":"Expected authorization in headers, but none provided.","errorCode":"ATP_2"},"requestId":"acc816c3-210c-400a-a551-42110dfebc00"}}curl: (3) URL rejected: Bad hostname**
I'm slightly irritated. The credentials are the same...in R I got at least a correct list of surveys.
* Another thing to try -- can you run this code to see a bit more detail about what is happening?
## put your survey ID here: fetch_url <- qualtRics::generate_url(query = "fetchsurvey", surveyID = "SV_xxx") raw_payload <- qualtRics:::create_raw_payload( label = TRUE, start_date = NULL, end_date = NULL, limit = NULL, time_zone = NULL, unanswer_recode = NULL, unanswer_recode_multi = NULL, include_display_order = TRUE, include_questions = NULL, breakout_sets = NULL ) res <- qualtRics:::qualtrics_api_request("POST", url = fetch_url, body = raw_payload) res$meta #> $requestId #> [1] "f52b2929-b24a-4c9d-88a6-e7c9d3ff660d" #> #> $httpStatus #> [1] "200 - OK"
Created on 2022-04-04 by the reprex package (v2.0.1)
**With "fetchsurvey" ist get an error!
Error in qualtRics::generate_url()
:
! Internal error: invalid URL generation query
Run rlang::last_trace()
to see where the error occurred.
Similar to the error reported by cndunham in issue #297. https://github.com/ropensci/qualtRics/issues/297
I changed to "fetchdescription", metioned by cndunham. Now I have no error in generate_url.
I switched "POST" to "GET", as mentioned by cndunham. Now I get: res <- qualtRics:::qualtrics_api_request("GET", url = fetch_url, body = raw_payload)
res$meta $httpStatus [1] "200 - OK"
$requestId [1] "0fd0334d-15c8-4483-85f8-fda074335c86"
$notice [1] "Request proxied. For faster response times, use this host instead: fra1.qualtrics.com"
So I think, Qualtrixs is proxying my request!
Best, Pierre
**
Let's go back to this, just to make sure:
curl --request GET \
--url https://conjoint.co1.qualtrics.com/API/v3/whoami \
--header 'x-api-token: YOURLONGAPITOKENHERE'
I may not have been clear enough but you need to use your base URL there in the terminal.
If you see info about your request being proxied, then do go ahead and use the recommended host instead of the base URL you had before.
Dear Julia,
curl --request GET --url https://UR_xxxSO.qualtrics.com/API/v3/whoami --header 'x-api-token: IUxQ4XmxxxxC7UzV23ww'
UR_xxxSO.qualtrics.com is my "xxx"-ed base URL IUxQ4XmxxxxC7UzV23ww is my "xxx"-ed API-ID.
I got:
{"meta":{"httpStatus":"400 - Bad Request","error":{"errorMessage":"Expected authorization in headers, but none provided.","errorCode":"ATP_2"},"requestId":"15886bb6-1745-4d36-8d76-4b918c0dad99"}}curl: (3) URL rejected: Bad hostname
Best, Pierre
Hmmm, that is not the error message you get for a wrong API token (that would be 401 and would have "Unrecognized X-API-TOKEN"). Seems like the header is not getting specified correctly. Is maybe something getting mangled when you copy and paste ? It should look exactly like this, with --
and regular single quotes '
and such:
curl --request GET \
--url https://conjoint.co1.qualtrics.com/API/v3/whoami \
--header 'x-api-token: YOURLONGAPITOKENHERE'
Hi Julia! Thank you for your patience!
curl --request GET \--url https://conjoint.co1.qualtrics.com/API/v3/whoami \--header 'x-api-token: IUxQ4Xmxxx23ww'
gives me:
curl: (3) URL rejected: Bad hostname
{"meta":{"httpStatus":"400 - Bad Request","error":{"errorMessage":"Expected authorization in headers, but none provided.","errorCode":"ATP_2"},"requestId":"6388361c-b0e8-436a-9712-c486076b02bb"}}curl: (3) URL rejected: Bad hostname
curl: (3) URL rejected: Port number was not a decimal number between 0 and 65535
curl: (3) URL rejected: Bad hostname
Without the "backslash" in front of "--":
curl --request GET --url https://conjoint.co1.qualtrics.com/API/v3/whoami --header 'x-api-token: IUxQ4XmExxx23ww'
gives me:
{"meta":{"httpStatus":"400 - Bad Request","error":{"errorMessage":"Expected authorization in headers, but none provided.","errorCode":"ATP_2"},"requestId":"7db0d3fc-fa0a-4221-9472-b56652e55087"}}curl: (3) URL rejected: Bad hostname
Seems to be a lack of authorisation? (Edit: more probably: "lack of brain" on my side :-))
Best, Pierre
Thank you for your patience on this! This is a tough thing to debug remotely. 😕
I think the first thing we need to do is figure out what combination of URL and token gives you a 200 when you use curl.
If I log into qualtrics.com and go to my user settings, I see a:
iad1
)I can set up a "who am I, Qualtrics?" curl command like this:
curl --request GET \
--url https://iad1.qualtrics.com/API/v3/whoami \
--header 'x-api-token: YOURFORTYCHARACTERAPITOKENHERE'
(Side note: we use \
in this curl command just as a line continuation syntax. If you are using newlines, use \
; if you are putting the curl command all on one line, then no \
.)
When I run that command in the terminal I get back results like this:
{
"result": {
"brandId": "conjoint",
"userId": "UR_8wfXXXXX",
"userName": "julia.silge@gmail.com",
"accountType": "UT_0Bf9UpXXXXX",
"firstName": "Julia",
"lastName": "Silge",
"email": "julia.silge@gmail.com",
"datacenter": "co1"
},
"meta": {
"requestId": "69611972-15b6-48d1-bcb8-67bdc72a2ae6",
"httpStatus": "200 - OK"
}
}
I used some "XXXX" here for some of my IDs but I don't know if that's actually very private info. It did seem to switch me to a different datacenter ID (which is one of the things we are looking for), but IMO the most important thing here is that this combination of URL and API token returned 200.
Can you look again at what your datacenter ID is and your API token and try out some combos of what you suspect are right? I do notice that you are not the first person to run into this. For example:
You might end up needing to chat with Qualtrics support to see why you can't authenticate correctly.
Dear Julia,
thank you again! Got "200 - OK" !!!!
C:\Users\pxxx.bxxxxr>curl --request GET --url "https://fra1.qualtrics.com/API/v3/whoami" --header "x-api-token: RBzfJ xxx nduR"
{
"result":{
"brandId": "kxxx",
"userId":"UR_0lArJRvW0BISISO",
"userName":"pxxx.bxxx@kxxx.de",
"accountType":"UT_3dBUKOs5wAT2mLW",
"firstName":"Pxxx",
"lastName":"Bxxx",
"email":"pxxx.bxxxx@kxxx.de",
"datacenter":"awsireland"
},
"meta":{
"requestId":"1f6cd64f-6c68-4956-b0a2-3d0a29d9bfc4",
"httpStatus":"200 - OK"
}
}
So, what ist the next step?
Best, Pierre
Oh, great news! 🎉
Request proxied. For faster response times, use this host instead:
If you see this, you will want to use that URL instead of your original base URL.
If you do not see any messages about proxying, then try fetch_survey()
again with the API token plus URL that give you a successful "who am I, Qualtrics?" with no proxying.
If it still doesn't work, can you run this code to see a bit more detail about what is happening?
fetch_url <- qualtRics::generate_url(query = "exportresponses", surveyID = "SV_83XXXXX")
raw_payload <- qualtRics:::create_raw_payload(
format = "csv",
useLabels = TRUE,
startDate = NULL,
endDate = NULL,
timeZone = NULL,
limit = NULL,
seenUnansweredRecode = NULL,
multiselectSeenUnansweredRecode = NULL,
includeDisplayOrder = TRUE,
questionIds = NULL,
embeddedDataIds = NULL,
surveyMetadataIds = NULL,
breakoutSets = NULL
)
res <- qualtRics:::qualtrics_api_request("POST", url = fetch_url, body = raw_payload)
res$meta
#> $requestId
#> [1] "88314239-93ac-43d6-a0d1-93180f4476b8"
#>
#> $httpStatus
#> [1] "200 - OK"
Created on 2024-07-31 with reprex v2.1.1
Dear Julia,
thanks a lot!! I think it works!
> fetch_url <- qualtRics::generate_url(query = "exportresponses", surveyID = "SV_a9kxxxx")
> raw_payload <- qualtRics:::create_raw_payload(
+ format = "csv",
+ useLabels = TRUE,
+ startDate = NULL,
+ endDate = NULL,
+ timeZone = NULL,
+ limit = NULL,
+ seenUnansweredRecode = NULL,
+ multiselectSeenUnansweredRecode = NULL,
+ includeDisplayOrder = TRUE,
+ questionIds = NULL,
+ embeddedDataIds = NULL,
+ surveyMetadataIds = NULL,
+ breakoutSets = NULL
+ )
> res <- qualtRics:::qualtrics_api_request("POST", url = fetch_url, body = raw_payload)
> res$meta
$requestId
[1] "b05e0909-702f-4672-b9aa-62094846746d"
$httpStatus
[1] "200 - OK"
.... and I got a data.frame with results from one of our questionnaires! Wonderfull! (...some problems(...) with dplyr reports, but I will analyse them, first:-))
I love you, Julia, ... and R, of course! So good to get so persistent, kind and patient support! Thank you!! Hava a nice day! Best, Pierre
Oh, I am so glad we got it figured out! 🙌 Let us know if you have any further questions.
Hi!
I'm a physician with the task to evaluate our patient satisfaction surevey via Qualtrics. I love R.
With following code I get an error (400):
##########################################
Your Qualtrics key and base URL have been stored in your .Renviron.
To use now, restart R or run
readRenviron("~/.Renviron")
########################## So, I'm having access to our Qualtrics via Token and Base-URL. I'm getting a correct list of our surveys. I can C&P the Survey-IDs. What did I miss to get the 400-error? Thank you, Pierre