Ask500 beta

Ask500 API

The Ask500People API provides access to most of the user services found on the website. You can use it to create campaigns, vote on campaigns, get the results of a campaign, and query the system for campaigns.

The API uses a form of authentication to control access to non-public content and actions. This authentication is done using an API key that is public and a secret API key which is known only to Ask500People and you. You can find your key pair in your account. More details on authentication can be found in the documentation for specific API versions.

Some of the vocabulary used in these docs can seem a bit cryptic to people not familiar with Ask500, so it is recommend to familiarize yourself with the glossary.

JSON API

The JSON version of the API uses HTTP GET/POST requests to make calls to the Ask500People servers. The responses are returned formated as JSON. HTTP GET and HTTP POST may be used interchangeably, though for certain calls (create campaign) POST may be preferred due to the length restrictions of the GET query string. Special accommodations have been made for clients written in JavaScript that run in a web browser.

Examples

Examples make things so much easier. Here you will find several examples of common API usage cases. Most of these examples use cURL to perform the HTTP GET/POST requests. If you use a *-nix style OS you probably already have cURL installed. If not, you can get it from the cURL download page.

Vote

Say you want to answer a campaign (ID 1144 in this example). First you need to perform an ask call to register a visitor, and retrieve the campaign's details (assuming you don't already have them stored locally).

$ curl "http://www.ask500people.com/api/1.0/ask.js?k=someApiKey&i=1144"
{"status_code":200,"status_message":"OK","campaign":{"question":"How are you today?","type":"text","url_name":"how-are-you-today","id":"1144","breed":"everywhere","options":[{"id":"3266","url":null,"media":"bad","mime_type":"text\/plain"},{"id":"3267","url":null,"media":"ugly","mime_type":"text\/plain"},{"id":"3265","url":null,"media":"good","mime_type":"text\/plain"}]},"visitor":{"id":"19002","lat":"45.518398","lng":"-122.655403"}}
$

Now you make your decision about how you are feeling, and note the desired option's ID. We feel “good” today, so we want the option with ID 3265. Now to register our decision, we need to make a vote call using the visitor ID from the ask call's response (19002 in this case) and the desired option ID (3265).

$ curl "http://www.ask500people.com/api/1.0/vote.js?k=someApiKey&v=19002&o=3265"
{"status_code":200,"status_message":"OK"}
$

We get back a response with a status of 200 (“OK”), indicating that our vote was successfully recorded. Wooo!

List

If you wanted to get a list of a user's public campaigns, you would make a list call. As long as you are after the campaigns in a users profile, no authentication is needed.

$ curl "http://www.ask500people.com/api/1.0/list.js?k=someApiKey&u=ixpah"
{"status_code":200,"status_message":"OK","campaigns":[{"question":"How many cups of caffeinated beverages do you drink in a day?","type":"text","url_name":"how-many-cups-of-caffeinated-beverages-do-you-drink-in-a-day","id":"13465","breed":"everywhere","options":[{"id":"50436","url":null,"media":"None, I don't drink caffeinated beverages.","mime_type":"text\/plain"},{"id":"50437","url":null,"media":"1 cup a day or less.","mime_type":"text\/plain"},{"id":"50438","url":null,"media":"2-3 cups a day.","mime_type":"text\/plain"},{"id":"50439","url":null,"media":"More then 3 cups a day.","mime_type":"text\/plain"}]},{"question":"Would you support a casino in your area?","type":"range_likely","url_name":"would-you-support-a-casino-in-your-area","id":"13464","breed":"everywhere","options":[{"id":"50431","url":null,"media":"Very Unlikely","mime_type":"text\/plain"},{"id":"50432","url":null,"media":"Unlikely","mime_type":"text\/plain"},{"id":"50433","url":null,"media":"Not Sure","mime_type":"text\/plain"},{"id":"50434","url":null,"media":"Likely","mime_type":"text\/plain"},{"id":"50435","url":null,"media":"Very Likely","mime_type":"text\/plain"}]},{"question":"Do you listen to music while you read?","type":"text","url_name":"do-you-listen-to-music-while-you-read","id":"13206","breed":"everywhere","options":[{"id":"49551","url":null,"media":"Yes.","mime_type":"text\/plain"},{"id":"49552","url":null,"media":"No.","mime_type":"text\/plain"},{"id":"49553","url":null,"media":"Sometimes.","mime_type":"text\/plain"}]},{"question":"Do you prefer pseudoephedrine or phenylephrine (both are nasal decongestants)?","type":"text","url_name":"do-you-prefer-pseudoephedrine-or-phenylephrine-both-are-nasal-decongestants","id":"13205","breed":"everywhere","options":[{"id":"49547","url":null,"media":"I prefer pseudoephedrine.","mime_type":"text\/plain"},{"id":"49548","url":null,"media":"I prefer phenylephrine.","mime_type":"text\/plain"},{"id":"49549","url":null,"media":"I don't have a preference.","mime_type":"text\/plain"},{"id":"49550","url":null,"media":"I don't know what one or both of those drugs are.","mime_type":"text\/plain"}]},{"question":"Do you have an allergy to any medication?","type":"yesno","url_name":"do-you-have-an-allergy-to-any-medication","id":"13204","breed":"everywhere","options":[{"id":"49545","url":"http:\/\/www.ask500people.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"49546","url":"http:\/\/www.ask500people.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Are video games replacing "traditional" entertainment sources like books, music, films, etc. ?","type":"range_likely","url_name":"are-video-games-replacing-traditional-entertainment-sources-like-books-music-films-etc-","id":"13203","breed":"everywhere","options":[{"id":"49538","url":null,"media":"Very Unlikely","mime_type":"text\/plain"},{"id":"49539","url":null,"media":"Unlikely","mime_type":"text\/plain"},{"id":"49540","url":null,"media":"Not Sure","mime_type":"text\/plain"},{"id":"49541","url":null,"media":"Likely","mime_type":"text\/plain"},{"id":"49542","url":null,"media":"Very Likely","mime_type":"text\/plain"}]},{"question":"Would you clone yourself?","type":"yesno","url_name":"would-you-clone-yourself","id":"13202","breed":"everywhere","options":[{"id":"49536","url":"http:\/\/www.ask500people.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"49537","url":"http:\/\/www.ask500people.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Are you thinking of upgrading your computer in the next 6 months?","type":"text","url_name":"are-you-thinking-of-upgrading-your-computer-in-the-next-6-months","id":"13054","breed":"everywhere","options":[{"id":"48932","url":null,"media":"Yes, I plan to buy one in the next 6 months.","mime_type":"text\/plain"},{"id":"48933","url":null,"media":"No, I don't plan to buy one in the next 6 months.","mime_type":"text\/plain"},{"id":"48934","url":null,"media":"I don't currently own a computer, but plan to buy one in the next 6 months.","mime_type":"text\/plain"},{"id":"48935","url":null,"media":"I don't currently own a computer, and I don't plan to buy one in 6 months.","mime_type":"text\/plain"}]},{"question":"Would you support instant-runoff voting for elections in your country?","type":"text","url_name":"would-you-support-instant-runoff-voting-for-elections-in-your-country","id":"12637","breed":"everywhere","options":[{"id":"47227","url":null,"media":"Yes","mime_type":"text\/plain"},{"id":"47228","url":null,"media":"No","mime_type":"text\/plain"},{"id":"47229","url":null,"media":"I don't know what instant-runoff voting is.","mime_type":"text\/plain"},{"id":"47230","url":null,"media":"We already use instant-runoff voting in my country.","mime_type":"text\/plain"}]},{"question":"Will computer waste (including energy usage) be the dominant form of pollution in the world in 2020?","type":"range_likely","url_name":"will-computer-waste-including-energy-usage-be-the-dominant-form-of-pollution-in-the-world-in-2020","id":"12636","breed":"everywhere","options":[{"id":"47222","url":null,"media":"Very Unlikely","mime_type":"text\/plain"},{"id":"47223","url":null,"media":"Unlikely","mime_type":"text\/plain"},{"id":"47224","url":null,"media":"Not Sure","mime_type":"text\/plain"},{"id":"47225","url":null,"media":"Likely","mime_type":"text\/plain"},{"id":"47226","url":null,"media":"Very Likely","mime_type":"text\/plain"}]},{"question":"Do you believe in plate tectonics?","type":"range_likely","url_name":"do-you-believe-in-plate-tectonics","id":"12635","breed":"everywhere","options":[{"id":"47217","url":null,"media":"Very Unlikely","mime_type":"text\/plain"},{"id":"47218","url":null,"media":"Unlikely","mime_type":"text\/plain"},{"id":"47219","url":null,"media":"Not Sure","mime_type":"text\/plain"},{"id":"47220","url":null,"media":"Likely","mime_type":"text\/plain"},{"id":"47221","url":null,"media":"Very Likely","mime_type":"text\/plain"}]},{"question":"Do you believe it is possible to reach absolute zero?","type":"range_likely","url_name":"do-you-believe-it-is-possible-to-reach-absolute-zero","id":"12634","breed":"everywhere","options":[{"id":"47212","url":null,"media":"Very Unlikely","mime_type":"text\/plain"},{"id":"47213","url":null,"media":"Unlikely","mime_type":"text\/plain"},{"id":"47214","url":null,"media":"Not Sure","mime_type":"text\/plain"},{"id":"47215","url":null,"media":"Likely","mime_type":"text\/plain"},{"id":"47216","url":null,"media":"Very Likely","mime_type":"text\/plain"}]},{"question":"How much do you like spicy (hot) food?","type":"range_like","url_name":"how-much-do-you-like-spicy-hot-food","id":"12633","breed":"everywhere","options":[{"id":"47207","url":null,"media":"Strongly Dislike","mime_type":"text\/plain"},{"id":"47208","url":null,"media":"Dislike","mime_type":"text\/plain"},{"id":"47209","url":null,"media":"Not Sure","mime_type":"text\/plain"},{"id":"47210","url":null,"media":"Like","mime_type":"text\/plain"},{"id":"47211","url":null,"media":"Strongly Like","mime_type":"text\/plain"}]},{"question":"Who is going to win the Super Bowl?","type":"text","url_name":"who-is-going-to-win-the-super-bowl","id":"12632","breed":"everywhere","options":[{"id":"47205","url":null,"media":"Giants","mime_type":"text\/plain"},{"id":"47206","url":null,"media":"Patriots","mime_type":"text\/plain"}]},{"question":""Where there is love, there is laughter" - Anonymous","type":"range_agree","url_name":"where-there-is-love-there-is-laughter---anonymous","id":"12631","breed":"everywhere","options":[{"id":"47200","url":null,"media":"Strongly Disagree","mime_type":"text\/plain"},{"id":"47201","url":null,"media":"Disagree","mime_type":"text\/plain"},{"id":"47202","url":null,"media":"Undecided","mime_type":"text\/plain"},{"id":"47203","url":null,"media":"Agree","mime_type":"text\/plain"},{"id":"47204","url":null,"media":"Strongly Agree","mime_type":"text\/plain"}]},{"question":"Are you traveling this holiday season?","type":"text","url_name":"are-you-traveling-this-holiday-season-8688","id":"8688","breed":"everywhere","options":[{"id":"31298","url":null,"media":"Yes, by plane.","mime_type":"text\/plain"},{"id":"31299","url":null,"media":"Yes, by car\/bus.","mime_type":"text\/plain"},{"id":"31300","url":null,"media":"Yes, by train.","mime_type":"text\/plain"},{"id":"31301","url":null,"media":"No.","mime_type":"text\/plain"}]},{"question":"Is beer a common drink in your country?","type":"yesno","url_name":"is-beer-a-common-drink-in-your-country","id":"6264","breed":"everywhere","options":[{"id":"22603","url":"http:\/\/www.ask500people.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"22604","url":"http:\/\/www.ask500people.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Do you like beer?","type":"yesno","url_name":"do-you-like-beer","id":"6263","breed":"everywhere","options":[{"id":"22601","url":"http:\/\/www.ask500people.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"22602","url":"http:\/\/www.ask500people.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Do you use multiple currencies in your day to day life?","type":"yesno","url_name":"do-you-use-multiple-currencies-in-your-day-to-day-life","id":"625","breed":"everywhere","options":[{"id":"2216","url":"http:\/\/www.ask500people.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"2217","url":"http:\/\/www.ask500people.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Are you worried about the microwave raditation that cellphones emit?","type":"yesno","url_name":"are-you-worried-about-the-microwave-raditation-that-cellphones-emit","id":"544","breed":"everywhere","options":[{"id":"1971","url":"http:\/\/www.ask500people.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"1972","url":"http:\/\/www.ask500people.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]}],"total_campaigns":"24"}
$

Wow, thats a lot of data back isn't it? Well, thats because the user “ixpah” has a lot of campaigns in their profile, and for each profile we return a full campaign object. To try and keep the size of the response down, we will only return 20 campaigns at a time for any list request. In the response above, you will note we got back 20 campaigns, and that the user “ixpah” has a total of 24 in their profile. If we wanted to get the last 4, we could do so with another list call. Only this time we want to add a page parameter (p) so that we get the second page of campaigns.

$ curl "http://www.ask500people.com/api/1.0/list.js?k=someApiKey&u=ixpah&p=2"
{"status_code":200,"status_message":"OK","campaigns":[{"question":"Do you have one or more compact florescent light bulbs (CFL) in your home?","type":"text","url_name":"do-you-have-one-or-more-compact-florescent-light-bulbs-cfl-in-your-home","id":"151","breed":"everywhere","options":[{"id":"553","url":null,"media":"Yes","mime_type":"text\/plain"},{"id":"554","url":null,"media":"No","mime_type":"text\/plain"},{"id":"555","url":null,"media":"I don't know what a CFL is.","mime_type":"text\/plain"},{"id":"556","url":null,"media":"I don't know.","mime_type":"text\/plain"}]},{"question":"Are you worried about natural disasters caused by climate change?","type":"yesno","url_name":"are-you-worried-about-natural-disasters-caused-by-climate-change","id":"146","breed":"everywhere","options":[{"id":"539","url":"http:\/\/www.ask500people.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"540","url":"http:\/\/www.ask500people.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Do you think China will be a good host of the 2008 Summer Olympic games?","type":"yesno","url_name":"do-you-think-china-will-be-a-good-host-of-the-2008-summer-olympic-games","id":"145","breed":"everywhere","options":[{"id":"537","url":"http:\/\/www.ask500people.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"538","url":"http:\/\/www.ask500people.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Do you believe in magic?","type":"yesno","url_name":"do-you-believe-in-magic-121","id":"121","breed":"everywhere","options":[{"id":"441","url":"http:\/\/www.ask500people.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"442","url":"http:\/\/www.ask500people.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]}],"total_campaigns":"24"}
$

And there we have it. All 24 campaigns found in Ixpah's profile have been downloaded.

Create

Creating a campaign via the API is a bit more complicated then the other two examples found here. Thats because there is no way to create a campaign w/o using authentication. This example assumes you have PHP 5 with the hash PECL extension installed. In this example, we are going to create a simple “yesno” type campaign, with a breed of “your_friends”. The question will read “Are you happy right now?”. We will use a create call to accomplish this.

$ curl "http://www.ask500people.com/api/1.0/create.js?k=someApiKey&t=yesno&q=Are+you+happy+right+now%3F"
{"status_code":403,"status_message":"Forbidden: Authentication failed","campaign":null}
$

Oh no! Our call failed! Thats because we didn't do any authentication, and create calls always require authentication. Before we go on, note how we URL encoded the question string (q) from “Are you happy right now?” to “Are+you+happy+right+now%3F”. In order to authenticate ourselves with the Ask500 servers, we will need to create a simple PHP script to do the HMAC-SHA1 calculation.

// Example HMAC-SHA1 signature calculator for Ask500People.com's JSON API. It
// will calculate the signature for any call given the call's parameters. No
// verification of the call's parameters will be performed.
// 
// Usage: ./ask500sign.php [args] <call>
// 
// This script accepts the following args depending on the <call> requested:
// 
// 	all calls:
// 	  -k <key>
//    -c <callback>
// 
// 	create call:
//	  -q "<question>"
//	  -t <type>
// 
//	  -a   // request an "everywhere" breed if present
// 	  -1 "<answer>" // the first answer for image and text types. Note: this script
// 			   // only supports URLs for image questions. It does not support
// 			   // the transmission of raw image data.
// 	  -2 "<answer>" // the second answer for image and text types.
// 	  -3 "<answer>" // the optional third answer for image and text types.
// 	  -4 "<answer>" // the optional fourth answer for image and text types.
//	ask, stop and delete calls:
// 	  -i <campaign id>
// 	vote call:
// 	  -v <visitor id>
// 	  -o <option id>
// 	result call:
// 	  -i <campaign id>
// 	  -v <visitor id>
// 	  -d 		// request details if present
// 	  -r <raw vote limit>
// 	list call:
// 	  -u <username>
// 	  -p <page>
// 
// For a detailed explanation of what each parameter means, please consult the API
// documentation at: http://docs.ask500people.com/doku.php?id=ask_500_api
// 
// Use getopt to parse command line arguments. A proper implementation would
// check the values for errors and ensure the required ones are present. But
// we are going for simple here.
$params = getopt("q:t:ak:1:2:3:4:v:i:o:dr:u:p:");
// Get the call from the last arg of the command line. This is kind of hacky.
$call = end($_SERVER['argv']);
 
 
// convert -a into a boolean true instead of getopt's boolean false
if (isset($params['a']))
{
	$params['a'] = true;
}
 
// convert -d into a boolean true instead of getopt's boolean false
if (isset($params['d']))
{
	$params['d'] = true;
}
 
// getopt doesnt have good longopt support, so we use -1 to -4 for answers,
// instead of the APIs o_1 to o_4. Here we convert to the APIs nomaclature.
for ($i=1; $i < 5; $i++)
{ 
	if (isset($params[$i]))
	{
		$params["o_{$i}"] = $params[$i];
		unset($params[$i]); // make sure to blank out the old keys
	}
}
 
// This is where you would put your secret key, gotten from
// http://www.ask500people.com/users/api_keys
$secret_key = "yourSecretKeyHereKeepItSAFE!"; 
 
// The signature must be accompanied with the date and time that the 
// signature was calculated. The date needs to be in the format specified 
// in RFC1123. PHP includes a constant with the format string for the
// date() function. The date and time that the signature was calculated
// must be within 15 minutes of when the call arives at the Ask500 webservers.
$sig_date = date(DATE_RFC1123);
// $message will hold the message we are constructing. It is this message
// that will be hashed by the HMAC-SHA1 algorithm to generate the signature.
// First we put the call name, followed by a new line, followed by the
// date and time the signature is being calculated. We don't put a newline
// at the end because we may not have any parameters, and dont want a trailing
// new line.
$message = "{$call}\n" . $sig_date;
 
 
// The parameters MUST be placed in the message in alphabetical order, so
// we sort them by key using SORT_STRING to make sure PHP uses the right
// ordering.
ksort($params, SORT_STRING);
foreach ($params as $key => $value)
{
	// the parameters are appended to the message, one per line. The
	// newline comes before the parameter, so that when we are done we
	// wont have a trailing newline.
	$message .= "\n{$key}: {$value}"; 
}
 
 
// This is the heart of the code. Here we call the hash_hmac function
// from the "hash" PECL extension (or PHP >= 5.1.2). This function will
// calculate the HMAC hash of the message using the secret key and one
// of many possible hashing algorithms. In this case we want to use the
// "sha1" algorithm so that the end result is a HMAC-SHA1 hash. This hash
// is our "signature".
$signature = hash_hmac('sha1', $message, $secret_key);
// Now we place the signature and the date and time it was generated into
// the parameters list.
$params['sig'] = $signature;
$params['sig_date'] = $sig_date;
 
// And finally, we use http_build_query() to turn the parameters list into
// a query string for our final request URL. The order that the parameters
// are placed into the query string is NOT important. Unlike with the order
// of the parameters in the message generated above.
$signed_url = "http://www.ask500people.com/api/1.0/{$call}.js?" . http_build_query($params);
// echo out the url and we are done.
echo $signed_url . "\n";

We will put the script in a file called “ask500sign.php” and give it permission to execute from the command line. Then we can use the script to sign any calls that need authentication. So lets try our create call again, only with authorization this time.

$ ./ask500sign.php -q "Are you happy right now?" -t yesno -k someApiKey create
http://www.ask500people.com/api/1.0/create.js?k=someApiKey&q=Are+you+happy+right+now%3F&t=yesno&sig=2d0312e3659cdf267a6bced82461aa66e043aeb4&sig_date=Wed%2C+26+Mar+2008+18%3A53%3A58+-0700
$ curl "http://www.ask500people.com/api/1.0/create.js?k=someApiKey&q=Are+you+happy+right+now%3F&t=yesno&sig=2d0312e3659cdf267a6bced82461aa66e043aeb4&sig_date=Wed%2C+26+Mar+2008+18%3A53%3A58+-0700"
{"status_code":200,"status_message":"OK","campaign":{"question":"Are you happy right now?","type":"yesno","url_name":"are-you-happy-right-now-16122","id":"16122","breed":"your_friends","options":[{"id":"59926","url":"http:\/\/www.ask500people.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"59927","url":"http:\/\/www.ask500people.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]}}
$

And there we go! Our campaign has been created and has an ID of 16122. We can see our newly created campaign at http://www.ask500people.com/questions/are-you-happy-right-now-16122. The campaign is already launched and ready to start collecting votes.

Parameter Passing

All parameters can be passed as part of the query string for HTTP GET requests, or as part of the payload for HTTP POST requests. All parameters are expected to be in the UTF-8 character set, and should be URL encoded as needed.

Authentication

Most API calls (create, stop, delete, etc.) require authentication to ensure there is no unauthorized access to your data. All authentication is done using an HMAC to sign each request. If the HMAC sent with the request matches the HMAC calculated server-side, the request will be deemed authenticated. To calculate the HMAC signature of a request, you must first construct a message that describes the request. The message MUST be in the format

{CALL}
{DATE}
{CANONICALIZED REQUEST PARAMETERS}

Where {CALL} is the lowercase name of the call (ie. ask, vote, results, etc.) being made, {DATE} is the time the request was made formated as an RFC1123 date, and {CANONICALIZED REQUEST PARAMETERS} is the sorted (ascending, ASCII order) list of the parameters sent along with the request. It is in the format

{PARAMETER 1 NAME}: {PARAMETER 1 VALUE}
{PARAMETER 2 NAME}: {PARAMETER 2 VALUE}
...
{PARAMETER n NAME}: {PARAMETER n VALUE}

The newlines found in both formats MUST be included. There is no trailing newline.

This message is then hashed using the HMAC-SHA1 hash function (as defined in RFC2104) with your API secret key for the key. The resulting signature is added to the request with the parameter name sig. The date used to create the signature ({DATE} above) should be added to the request with parameter name sig_date. This date must be within 15 minutes of the Ask500 web-server's current time.

Example

As always, an example is worth a thousand words. For a user with the API key “someApiKey” and the API secret key “76d507fd1ad3b81cebe38f0d40f37c64”, making the request

http://www.ask500people.com/api/1.0/vote.js?k=someApiKey&o=43&v=217

at “Tue, 18 Mar 2008 17:29:29 -0700”, you would generate the message

vote
Tue, 18 Mar 2008 17:29:29 -0700
k: someApiKey
o: 43
v: 217

This message would be hashed using HMAC-SHA1 into the signature “de45b2d8591ac2641c548ed7e4d539cef6c8496e”. This signature would be added to the request, along with the date, to give the signed request

http://www.ask500people.com/api/1.0/vote.js?k=someApiKey&o=43&v=217&sig=de45b2d8591ac2641c548ed7e4d539cef6c8496e&sig_date=Tue%2C+18+Mar+2008+17%3A29%3A29+-0700

Status Codes

To facilitate JavaScript usage of the API, errors will not return appropriate HTTP status codes in the HTTP response headers as one might expect. Instead, all responses contain two top level keys: status_code and status_message. status_code mimics the HTTP response status codes. For now it will either be 200, 400 or 403. status_message will contain some sort of a message describing the problem. Examples are “OK”, “Bad Request” or “Forbidden: Not approved for API use”.

JavaScript In Browsers

For the most part using the JSON API should be easy with JavaScript. The notable exception is the Same Origin Policy which prevents XMLHttpRequest from talking to remote servers (like the Ask500 servers). An excellent article on the subject (and its solution) can be found at XML.com. To this end the JSON API provides an optional callback function wrapper for every call. The parameter name is c and its value will have all non alphanumeric characters removed. The callback will be called with one parameter, the JSON object, when the response has loaded.

Callback Example

For a request like:

http://www.ask500people.com/api/1.0/ask.js?c=myCallback&k=someApiKey

You would get a response like:

myCallback({"status_code":200,"status_message":"OK","campaign":{"question":"An Example Question","type":"yesno","options":[{"id":"615","url":"http:\/\/www.ask500people.com\/img\/ask_content\/615","media":null,"mime_type":"image\/gif"},{"id":"614","url":"http:\/\/www.ask500people.com\/img\/ask_content\/614","media":null,"mime_type":"image\/gif"}]},"visitor":{"id":369}});

Note the myCallback(…); added to the response compared to the normal example.

Object Types

Most of the records returned by the API are standardized in format. Below you can find definitions for each record type. Since all data is returned as JSON, and all JSON objects are anonymous, the key which identifies the object also identifies the record type.

Campaign

A campaign is the combination of a question and its answers. Its the core unit of the Ask500 API. All calls interact with a campaign in one way or another.

Fields
  • question: the UTF-8 text of the campaign's question. NOTE This string is HTML entity encoded.
  • type: The type of campaign. Options are “yesno”, “image”, and “text”. “yesno” and “image” are functionally equivalent, except for “yesno” you can be sure there are only two options.
  • url_name: A unique human-readable name for the campaign. The Ask500 page for the campaign is found at http://www.ask500people.com/questions/{url_name}.
  • id: A unique ID number for the campaign.
  • breed: The breed of the campaign. Campaigns come in two breeds, “everywhere” and “your_friends”. “everywhere” means the campaign can be upvoted on, and may be asked on the whole Ask500 network. “your_friends” means the campaign will never go to the Ask500 network, and will only be visible to users you direct to it.
  • options: The array of option objects for the campaign (question answers).

Option

An option is a single answer for a campaign. The set of possible answers is comprised of 2 to 5 options.

Fields
  • id: The ID of the option.
  • url: A url for the options media (ie. image), or null if there isn't one (“text”, “range_likely”, “range_like”, “range_good” and “range_agree” options).
  • media: The raw media for an option (ie. UTF-8 text), or null for “range_star” or “image” campaigns. NOTE This string is HTML entity encoded.
  • mime_type: The mime_type of the media found in media and at url.

Visitor

A visitor is a representation of a person who saw a question. A visitor record is created for each person who sees a poll, and is required in order to vote.

Fields
  • id: The ID of the visitor record.
  • lng: The longitude of the visitor.
  • lat: The latitude of the visitor.

Vote

A vote represents a users actual response to the campaign's question. It associates a visitor's location with an option.

Fields
  • option_id: The ID of the option record that this visitor voted for.
  • lng: The longitude of the visitor when they voted.
  • lat: The latitude of the visitor when they voted.

Ask Call

Queries the Ask500People servers for a running campaign. You can either request a specific campaign, or request one selected at random from those currently running on the Ask500People network. This call registers a visitor if a campaign is found. Unlike most calls in the API, this call MUST originate from the visitor's IP address to protect against vote fraud. Only one vote is allowed per IP address per campaign. If the caller's IP address has already had a visitor logged for the requested campaign, the call will fail to find the campaign, The call returns the found campaign and the logged visitor on success. This call does not require authentication.

URL

http://www.ask500people.com/api/1.0/ask.js

Parameters

  • k: API Key (required)
  • c: Callback function (optional)
  • i: Campaign ID (optional) - Used to request an ask from a specific campaign.
  • test: Enables “test” mode (optional) - In “test” mode, there is always a running campaign of the appropriate type. The parameter's value should be one of “text”, “yesno”, “image”, “range_star”, “range_likely”, “range_like”, “range_good”, or “range_agree” depending on the desired type of campaign.

Response

  • status_code: The status code of the response.
  • status_message: The status message associated with the status_code.
  • visitior: The visitor object if a visit was logged, otherwise null.
  • campaign: The campaign object if one was found, otherwise null.

Example

For a request like:

http://www.ask500people.com/api/1.0/ask.js?k=someApiKey

You would get a response like:

{"status_code":200,"status_message":"OK","campaign":{"question":"How are you today?","type":"text","url_name":"how-are-you-today","id":"1144","breed":"everywhere","options":[{"id":"3266","url":null,"media":"bad","mime_type":"text\/plain"},{"id":"3267","url":null,"media":"ugly","mime_type":"text\/plain"},{"id":"3265","url":null,"media":"good","mime_type":"text\/plain"}]},"visitor":{"id":"19002","lat":"45.518398","lng":"-122.655403"}}

Vote Call

Registers a vote for a pre-existing visitor. It does not make sense to make a vote call without first making an ask_call. Unlike most calls in the API, this call MUST originate from the visitor's IP address to protect against vote fraud. This call does not require authentication.

URL

http://www.ask500people.com/api/1.0/vote.js

Parameters

  • k: API Key (required)
  • c: Callback function (optional)
  • v: Visitor ID (required) - The ID of the visitor who is voting.
  • o: Option ID (required) - The ID of the option the visitor is voting for.

Response

  • status_code: the status code of the response.
  • status_message: the status message associated with the status_code.

Example

For a request like:

http://www.ask500people.com/api/1.0/vote.js?k=someApiKey&v=370&o=615

You would get a response like:

{"status_code":200,"status_message":"OK"}

Result Call

This call returns the current results of a campaign. You get back the number of visitors, the number of votes, a breakdown of votes by option, and optionally up to 50 of the most recent vote objects. This call does not require authentication, but authentication can be used to access private campaigns.

URL

http://www.ask500people.com/api/1.0/result.js

Parameters

  • k: API Key (required)
  • c: Callback function (optional)
  • i: Campaign ID (optional) - The ID of the campaign you want results for (i or v are both listed as optional, but at least one is required).
  • v: Visitor ID (optional) - The ID of the visitor whose campaign you want results for, can be used in place of a Campaign ID (i).
  • d: Include Campaign Details (optional) - Set to “1” to retrieve the full campaign record in addition to results.
  • r: Raw Votes Limit (optional) - How many individual votes to return from the campaign in addition to the overall totals (defaults to none, max is 50) - if more than r votes exist, the most recent r are returned.

Response

  • status_code: The status code of the response.
  • status_message: The status message associated with the status_code.
  • campaign: The results if the campaign can be found, or null otherwise.
    • view_count: Total number of asks associated with the campaign.
    • vote_count: Total number of votes associated with the campaign.
    • options: Array of vote totals by option
      • id: The ID of the option that the votes correspond to.
      • vote_count: How many votes are there for the option in question.
    • votes: Array of the last r vote objects including latitude/longitude, if requested. If no votes are requsted, has a value of null.
    • details: The complete campaign object, if requested (d=1). Otherwise null.

Example

For a request like:

http://www.ask500people.com/api/1.0/result.js?k=docs&i=41&d=1&r=5

You would get a response like:

{"status_code":200,"status_message":"OK","campaign":{"view_count":"73","vote_count":17,"options":[{"id":147,"vote_count":10},{"id":148,"vote_count":7}],"votes":[{"option_id":"148","lat":"47.79530000","lng":"-122.20179700"},{"option_id":"147","lat":"47.79530000","lng":"-122.20179700"},{"option_id":"148","lat":"47.79530000","lng":"-122.20179700"},{"option_id":"147","lat":"35.82780100","lng":"-78.64209700"},{"option_id":"148","lat":"-10.00000000","lng":"-55.00000000"}],"details":{"question":"An example yesno&trade; question.","type":"yesno","url_name":"an-example-yesno-question","id":"41","options":[{"id":"147","url":"http:\/\/www.ask500people.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"148","url":"http:\/\/www.ask500people.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]}}}

Create Call

Used to create a new campaign associated with the authenticated user. Campaigns created via this API call are automatically submitted/launched upon creation. This call requires authentication.

URL

http://www.ask500people.com/api/1.0/create.js

Parameters

  • k: API Key (required)
  • c: Callback function (optional)
  • t: Campaign type (required) - The type of the campaign to create. See the campaign object definition for details on allowed values.
  • q: Question (required) - The question that the campaign is going to ask. Can be up to 125 characters long.
  • a: Ask on Ask500 network (optional) - If you want an “everywhere” breed, set this to “1”. Any other value, or not supplying a as a parameter will yield a “your_friends” breed.
  • o_1: First option (required for text/image type campaigns, ignored otherwise) - If the campaign is of type “text”, this should be the text to be used as the first option for the campaign. If the campaign is of type “image”, this should be either the raw image data (JPEG, PNG, GIF or BMP please) or a URL where the image can be found. If a URL is used, the image will be downloaded and stored on the Ask500 servers.
  • o_2: Second option (required for text/image type campaigns, ignored otherwise) - See o_1 above.
  • o_3: Third option (optional for text/image type campaigns, ignored otherwise) - See o_1 above.
  • o_4: Fourth option (optional for text/image type campaigns, ignored otherwise) - See o_1 above.

Response

  • status_code: the status code of the response.
  • status_message: the status message associated with the status_code.
  • campaign: The new campaign object on successful creation, otherwise null.

For a request like:

http://www.ask500people.com/api/1.0/create.js?k=docs&a=1&o_1=Yes&o_2=No&o_3=I+have+never+used+it.&q=Do+you+like+the+Ask500+API%3F&t=text

You would get a response like:

{"status_code":200,"status_message":"OK","campaign":{"question":"Do you like the Ask500 API?","type":"text","url_name":"do-you-like-the-ask500-api-1148","id":"1148","breed":"everywhere","options":[{"id":"3277","url":null,"media":"Yes","mime_type":"text\/plain"},{"id":"3278","url":null,"media":"No","mime_type":"text\/plain"},{"id":"3279","url":null,"media":"I have never used it.","mime_type":"text\/plain"}]}}

Stop Call

Used to stop a running “your_friends” campaign. Meaningless for “everywhere” campaigns. This call requires authentication.

URL

http://www.ask500people.com/api/1.0/stop.js

Parameters

  • k: API Key (required)
  • c: Callback function (optional)
  • i: Campaign ID (required) - The ID of the campaign you wish to stop.

Response

  • status_code: the status code of the response.
  • status_message: the status message associated with the status_code.

For a request like:

http://www.ask500people.com/api/1.0/stop.js?k=docs&i=1147

You would get a response like:

{"status_code":200,"status_message":"OK"}

Delete Call

Used to delete a campaign from Ask500. The campaign must belong to the authenticated user. If the campaign is an “everywhere” campaign, it can only be deleted prior to being run on the Ask500 network. Once it has been run on the network, it can never be deleted. This call requires authentication.

URL

http://www.ask500people.com/api/1.0/delete.js

Parameters

  • k: API Key (required)
  • c: Callback function (optional)
  • i: Campaign ID (required) - The ID of the campaign you wish to delete.

Response

  • status_code: the status code of the response.
  • status_message: the status message associated with the status_code.

For a request like:

http://www.ask500people.com/api/1.0/delete.js?k=docs&i=1147

You would get a response like:

{"status_code":200,"status_message":"OK"}

List Call

Returns a list of all the campaigns owned by the requested user. If the requested user isn't the authenticated user, only campaigns visible in the requested user's profile will be retuned. Only 20 campaigns (at most) are returned per request. Campaigns are returned ordered by creation date in descending order. This call does not require authentication, but without authentication you can only access campaigns found in the authenticated users profile.

URL

http://www.ask500people.com/api/1.0/list.js

Parameters

  • k: API Key (required)
  • c: Callback function (optional)
  • u: User name (required) - The user name of the user you wish to get a campaign list for.
  • p: Page (optional) - The page of the campaign list to return. Defaults to “1” (the first page).

Response

  • status_code: The status code of the response.
  • status_message: The status message associated with the status_code.
  • campaigns: The array of campaign objects that represent the user's campaign list. Contains at most 20 objects, sorted in descending order by creation time.
  • total_campaigns: The total number of campaigns in the user's campaign list (not just the ones on this page of results).

For a request like:

http://www.ask500people.com/api/1.0/list.js?k=docs&p=2&u=ixpah

You would get a response like:

{"status_code":200,"status_message":"OK","campaigns":[{"question":"Dsafsdds  dfsfds","type":"text","url_name":"dsafsdds-dfsfds","id":"1119","breed":"everywhere","options":[{"id":"3163","url":null,"media":"dsaf sd  sdffds","mime_type":"text\/plain"},{"id":"3164","url":null,"media":"asdf dfsdfsa","mime_type":"text\/plain"},{"id":"3165","url":null,"media":"sad fdsdsfsd a","mime_type":"text\/plain"}]},{"question":"Adsf fdsdfsf ds","type":"range_likely","url_name":"adsf-fdsdfsf-ds","id":"1118","breed":"everywhere","options":[{"id":"3158","url":null,"media":"Very Unlikely","mime_type":"text\/plain"},{"id":"3159","url":null,"media":"Unlikely","mime_type":"text\/plain"},{"id":"3160","url":null,"media":"Not Sure","mime_type":"text\/plain"},{"id":"3161","url":null,"media":"Likely","mime_type":"text\/plain"},{"id":"3162","url":null,"media":"Very Likely","mime_type":"text\/plain"}]},{"question":"Ghdj jdhjjh d","type":"yesno","url_name":"ghdj-jdhjjh-d","id":"1117","breed":"everywhere","options":[{"id":"3156","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3157","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Ghdjd hgjghjd ghj d","type":"yesno","url_name":"ghdjd-hgjghjd-ghj-d","id":"1116","breed":"everywhere","options":[{"id":"3154","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3155","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"hgjghjhjgjgh","type":"yesno","url_name":"hgjghjhjgjgh","id":"1115","breed":"everywhere","options":[{"id":"3152","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3153","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Dfga dfg dfggdf","type":"yesno","url_name":"dfga-dfg-dfggdf","id":"1114","breed":"everywhere","options":[{"id":"3150","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3151","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Fdg dfgfdgdfg dfg","type":"text","url_name":"fdg-dfgfdgdfg-dfg","id":"1113","breed":"everywhere","options":[{"id":"3148","url":null,"media":"sfg sdfgg gsf d","mime_type":"text\/plain"},{"id":"3149","url":null,"media":"sfg hhfgg fh","mime_type":"text\/plain"}]},{"question":"Dfgf sdfgdg f gdfgdf","type":"yesno","url_name":"dfgf-sdfgdg-f-gdfgdf","id":"1112","breed":"everywhere","options":[{"id":"3146","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3147","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Fgs hfghhfg h fg","type":"range_agree","url_name":"fgs-hfghhfg-h-fg","id":"1111","breed":"everywhere","options":[{"id":"3141","url":null,"media":"Strongly Disagree","mime_type":"text\/plain"},{"id":"3142","url":null,"media":"Disagree","mime_type":"text\/plain"},{"id":"3143","url":null,"media":"Undecided","mime_type":"text\/plain"},{"id":"3144","url":null,"media":"Agree","mime_type":"text\/plain"},{"id":"3145","url":null,"media":"Strongly Agree","mime_type":"text\/plain"}]},{"question":"Fdsg sgdffgd gfd","type":"range_likely","url_name":"fdsg-sgdffgd-gfd","id":"1110","breed":"everywhere","options":[{"id":"3136","url":null,"media":"Very Unlikely","mime_type":"text\/plain"},{"id":"3137","url":null,"media":"Unlikely","mime_type":"text\/plain"},{"id":"3138","url":null,"media":"Not Sure","mime_type":"text\/plain"},{"id":"3139","url":null,"media":"Likely","mime_type":"text\/plain"},{"id":"3140","url":null,"media":"Very Likely","mime_type":"text\/plain"}]},{"question":"Fdsg dfggfd","type":"range_star","url_name":"fdsg-dfggfd","id":"1109","breed":"everywhere","options":[{"id":"3131","url":"http:\/\/dev.ask500.com\/img\/ask_content\/3131","media":null,"mime_type":"image\/gif"},{"id":"3132","url":"http:\/\/dev.ask500.com\/img\/ask_content\/3132","media":null,"mime_type":"image\/gif"},{"id":"3133","url":"http:\/\/dev.ask500.com\/img\/ask_content\/3133","media":null,"mime_type":"image\/gif"},{"id":"3134","url":"http:\/\/dev.ask500.com\/img\/ask_content\/3134","media":null,"mime_type":"image\/gif"},{"id":"3135","url":"http:\/\/dev.ask500.com\/img\/ask_content\/3135","media":null,"mime_type":"image\/gif"}]},{"question":"Fgsh fghdfgads dfgad","type":"yesno","url_name":"fgsh-fghdfgads-dfgad","id":"1108","breed":"everywhere","options":[{"id":"3129","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3130","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Fgsh sfgghfhfg h gf","type":"yesno","url_name":"fgsh-sfgghfhfg-h-gf","id":"1107","breed":"everywhere","options":[{"id":"3127","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3128","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Fsgh fghsgfhfgh h gfs","type":"yesno","url_name":"fsgh-fghsgfhfgh-h-gfs","id":"1106","breed":"everywhere","options":[{"id":"3125","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3126","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Fdag dfgffgda fg dagdf","type":"yesno","url_name":"fdag-dfgffgda-fg-dagdf","id":"1105","breed":"everywhere","options":[{"id":"3123","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3124","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Fg fhgfh hfg s","type":"range_likely","url_name":"fg-fhgfh-hfg-s","id":"1104","breed":"everywhere","options":[{"id":"3118","url":null,"media":"Very Unlikely","mime_type":"text\/plain"},{"id":"3119","url":null,"media":"Unlikely","mime_type":"text\/plain"},{"id":"3120","url":null,"media":"Not Sure","mime_type":"text\/plain"},{"id":"3121","url":null,"media":"Likely","mime_type":"text\/plain"},{"id":"3122","url":null,"media":"Very Likely","mime_type":"text\/plain"}]},{"question":"Dafg dfa dfg dfggaf","type":"yesno","url_name":"dafg-dfa-dfg-dfggaf","id":"1103","breed":"everywhere","options":[{"id":"3116","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3117","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Dfg ada dfggd gf","type":"yesno","url_name":"dfg-ada-dfggd-gf","id":"1102","breed":"everywhere","options":[{"id":"3114","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3115","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Adfg dgfsgh h dfgdfgh","type":"yesno","url_name":"adfg-dgfsgh-h-dfgdfgh","id":"1101","breed":"everywhere","options":[{"id":"3112","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3113","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]},{"question":"Ragegrgreert  ergd afdgfgfd","type":"yesno","url_name":"ragegrgreert-ergd-afdgfgfd","id":"1100","breed":"everywhere","options":[{"id":"3110","url":"http:\/\/dev.ask500.com\/img\/results\/yes.gif","media":"Yes","mime_type":"text\/plain"},{"id":"3111","url":"http:\/\/dev.ask500.com\/img\/results\/no.gif","media":"No","mime_type":"text\/plain"}]}],"total_campaigns":"447"}

Glossary

  • campaign: Ask500People calls a question with its option answers and any results a campaign. A good synonym would be “poll”.
  • question: A question is the part of a campaign designed to elicit information. For now these are always sentences.
  • visitor: Someone who sees the question part of a campaign in a context where they COULD vote on the campaign.
  • type: In the context of a campaign, type referrers to what sort of answers the campaign has. Image answers for example, or text answers, or a range of stars.
  • breed: In the context of a campaign, breed referrers to where the campaign will run.