Using the Qualtrics API with PHP and javascript to create custom reports

Qualtrics.com is an extraordinarily full-featured online survey application that offers nearly every type of built-in report on your survey data you could ever want. But eventually, there comes a time when nothing but a custom report will do. Or you may want to integrate Qualtrics data into another application. For those times, Qualtrics has an extensive API which allows access to both data and functionality.

Qualtrics University doesn’t have many details of how to use the API, so to help you get started, I’m providing an example of how I used the Qualtrics API with a PHP proxy and Adobe’s Spry Framework to build a simple custom report.



The survey I used for this report is a graded quiz, with the user’s name and ID number sent to Qualtrics in the survey launch link and this information can be retrieved with the quiz results. The report displays quiz raw and percentage scores, completion date and the user’s name and ID number. The report can be easily searched for the name or ID number of a given user.

2011-04-11_16-56-54.jpg

Steps to build a similar report:

  • Create a survey to test with. Take the survey a number of times so that there will be some result data to report on.
  • Ask Qualtrics’ customer service for a copy of the Qualtrics API documentation.
  • Create a new user account on Qualtrics.com who will be used only for API-related tasks.
  • Assign the API-user rights to use the API. You will need administrator access to do this, so you may have to ask Qualtrics for help if you are not a brand-administrator.
  • Set the rights on the test survey you created to collaborate with the API-user account so that it has reporting rights for that survey.
  • Copy my modified version of Simple PHP Proxy from github and add in your own API-user account information where indicated. Test the proxy to make sure it is working.
  • Examine the results and decide which fields should go into your report
  • Modify my HTML to display the fields you are interested in.


Proxy page

Javascript cannot access content in remote webpages without cross-domain security limitations, so you must use some sort of server-side proxy to act as an intermediary between the Javascript and the remote data source. The proxy makes the request for the data to the remote server, and returns the results back to the javascript.

Scroll down and modify the lines highlighted in yellow with your own information.

Modify the Simple PHP Proxy code where indicated with yellow highlighting

<?PHP

// Script: Simple PHP Proxy: Get external HTML, JSON and more! // // *Version: 1.6, Last updated: 1/24/2009* // // Project Home - http://benalman.com/projects/php-simple-proxy/ // GitHub - http://github.com/cowboy/php-simple-proxy/ // Source - http://github.com/cowboy/php-simple-proxy/raw/master/ba-simple-proxy.php // // About: License // // Copyright (c) 2010 "Cowboy" Ben Alman, // Dual licensed under the MIT and GPL licenses. // http://benalman.com/about/license/ // // About: Examples // // This working example, complete with fully commented code, illustrates one way // in which this PHP script can be used. // // Simple - http://benalman.com/code/projects/php-simple-proxy/examples/simple/ // // About: Release History // // 1.6 - (1/24/2009) Now defaults to JSON mode, which can now be changed to // native mode by specifying ?mode=native. Native and JSONP modes are // disabled by default because of possible XSS vulnerability issues, but // are configurable in the PHP script along with a url validation regex. // 1.5 - (12/27/2009) Initial release // // Topic: GET Parameters // // Certain GET (query string) parameters may be passed into ba-simple-proxy.php // to control its behavior, this is a list of these parameters. // // url - The remote URL resource to fetch. Any GET parameters to be passed // through to the remote URL resource must be urlencoded in this parameter. // mode - If mode=native, the response will be sent using the same content // type and headers that the remote URL resource returned. If omitted, the // response will be JSON (or JSONP). <Native requests> and <JSONP requests> // are disabled by default, see <Configuration Options> for more information. // callback - If specified, the response JSON will be wrapped in this named // function call. This parameter and <JSONP requests> are disabled by // default, see <Configuration Options> for more information. // user_agent - This value will be sent to the remote URL request as the // `User-Agent:` HTTP request header. If omitted, the browser user agent // will be passed through. // send_cookies - If send_cookies=1, all cookies will be forwarded through to // the remote URL request. // send_session - If send_session=1 and send_cookies=1, the SID cookie will be // forwarded through to the remote URL request. // full_headers - If a JSON request and full_headers=1, the JSON response will // contain detailed header information. // full_status - If a JSON request and full_status=1, the JSON response will // contain detailed cURL status information, otherwise it will just contain // the `http_code` property. // // Topic: POST Parameters // // All POST parameters are automatically passed through to the remote URL // request. // // Topic: JSON requests // // This request will return the contents of the specified url in JSON format. // // Request: // // > ba-simple-proxy.php?url=http://example.com/ // // Response: // // > { "contents": "<html>...</html>", "headers": {...}, "status": {...} } // // JSON object properties: // // contents - (String) The contents of the remote URL resource. // headers - (Object) A hash of HTTP headers returned by the remote URL // resource. // status - (Object) A hash of status codes returned by cURL. // // Topic: JSONP requests // // This request will return the contents of the specified url in JSONP format // (but only if $enable_jsonp is enabled in the PHP script). // // Request: // // > ba-simple-proxy.php?url=http://example.com/&callback=foo // // Response: // // > foo({ "contents": "<html>...</html>", "headers": {...}, "status": {...} }) // // JSON object properties: // // contents - (String) The contents of the remote URL resource. // headers - (Object) A hash of HTTP headers returned by the remote URL // resource. // status - (Object) A hash of status codes returned by cURL. // // Topic: Native requests // // This request will return the contents of the specified url in the format it // was received in, including the same content-type and other headers (but only // if $enable_native is enabled in the PHP script). // // Request: // // > ba-simple-proxy.php?url=http://example.com/&mode=native // // Response: // // > <html>...</html> // // Topic: Notes // // * Assumes magic_quotes_gpc = Off in php.ini // // Topic: Configuration Options // // These variables can be manually edited in the PHP file if necessary. // // $enable_jsonp - Only enable <JSONP requests> if you really need to. If you // install this script on the same server as the page you're calling it // from, plain JSON will work. Defaults to false. // $enable_native - You can enable <Native requests>, but you should only do // this if you also whitelist specific URLs using $valid_url_regex, to avoid // possible XSS vulnerabilities. Defaults to false. // $valid_url_regex - This regex is matched against the url parameter to // ensure that it is valid. This setting only needs to be used if either // $enable_jsonp or $enable_native are enabled. Defaults to '/.*/' which // validates all URLs. // // ############################################################################

// Change these configuration options if needed, see above descriptions for info. $enable_jsonp = false; $enable_native = true; //**************************************// //$valid_url_regex = '/.*/'; //***modify the line below to allow only your domain, or uncomment the line above this to allow all domains ***// $valid_url_regex = '/http://yourdomain.com/*/';

&mode&&&&>

>&&&&&>

>&&""

>

<""""><""""><><""""><><><>

<><""""><><""""><><"">"&"""

"&"""""""""""""""""""""""""""""""

""""

 

""

""

"""><"""""

""

""""

""""""&&&&

<>

<><>

 

<""><""><""""""""""><<"""""">><>

<><""""><""""""""><"""">

<><><""""""><""><><><""""""><""><><><><"""""">

<""><""""><>&<><""""><><""""><><""""><><""""><><""""><><""""><><""""><><><""""><""><><""><><><><""><><><><><><""><><""><><><><>

<><>

<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>