API Documentation
API Overview
The Burning Man PlayaEvents API is free for you to use and build with.The API currently supports two formats, XML and JSON. By default it will return JSON. If you wish to consume XML, pass the API the keypair format=xml. If you want JSONP, provide the keypair callback=myclbk.
Methods
The API supports the following methods to receive and manipulate PlayaEvents data.Events
Public API Methods using HTTP GET
-
Retrieve All Events in 2009
playaevents.burningman.com/api/0.2/2009/event/
jQuery Events example [source] -
Retrieve Event with ID 1676
playaevents.burningman.com/api/0.2/2011/event/1676/
-
Events starting after Sept 1st
playaevents.burningman.com/api/0.2/2011/event/?start_time=2011-09-01%2018:00
-
Events before Sept 1st
playaevents.burningman.com/api/0.2/2011/event/?end_time=2011-09-01%2018:00
-
Events between Sept 1st and Sept 2nd
playaevents.burningman.com/api/0.2/2011/event/?end_time=2011-09-02%2018:00&start_time=2011-09-01%2018:00
-
You don't have to specify the time if you don't want to as well
playaevents.burningman.com/api/0.2/2011/event/?end_time=2011-09-01&start_time=2011-09-02
API methods requiring authentication
These methods must be signed as explained below in the section titled "Authentication"
-
Delete an event with ID 1676
Send an HTTP DELETE to the url:playaevents.burningman.com/api/0.2/2011/event/1676/
-
Create a new event
Send an HTTP POST to the url:playaevents.burningman.com/api/0.2/2011/event/
The POST should have any or all of the fields:- year: a 4 digit string
- print_description: text
- url: text
- contact_email: text
- other_location: text
- slug: text (usually autocalculated, not needed)
- moderation: U, A, or R. U=unreviewed, A=Accepted, R=Rejected
- hosted_by_camp: the camp id, as retrieved using the camp API method
- located_at_art: the art id, as retrieved using the art installation API method
- check_location: boolean “TRUE” or “FALSE”
- all_day: boolean “TRUE” or “FALSE”
- list_online: boolean “TRUE” or “FALSE”
- list_contact_online: boolean “TRUE” or “FALSE”
-
Edit event #1676
Send an HTTP PUT to the url:playaevents.burningman.com/api/0.2/2011/event/1676/
The PUT should have any or all of the fields listed above for the POST.
Theme Camps
Public API Methods using HTTP GET
-
playaevents.burningman.com/api/0.2/2011/camp/
jQuery Theme Camps example [source] -
Camp with id 3510
playaevents.burningman.com/api/0.2/2011/camp/3510/
jQuery Theme Camp example [source]
API methods requiring authentication
These methods must be signed as explained below in the section titled "Authentication"
-
Delete the camp with ID 1676
Send an HTTP DELETE to the url:playaevents.burningman.com/api/0.2/2011/camp/1676/
-
Create a new camp
Send an HTTP POST to the url:playaevents.burningman.com/api/0.2/2011/camp/
The POST should have any or all of the fields:- year: a 4 digit string
- name: text
- print_description: text
- url: text
- hometown: text
- slug: text (usually autocalculated, not needed)
- list_online: boolean “TRUE” or “FALSE”
- circular_street: id of the street as retrieved using the Circular street API method
- time_street: id of the street as retrieved using the Time street API method
-
Edit camp #1676
Send an HTTP PUT to the url:playaevents.burningman.com/api/0.2/2011/event/1676/
The PUT should have any or all of the fields listed above for the POST.
Art Installations
Public API Methods using HTTP GET
-
List all art for 2011
playaevents.burningman.com/api/0.2/2011/art/
jQuery Art Listings example [source] -
Art with ID 1077
playaevents.burningman.com/api/0.2/2011/art/1077/
jQuery Art example [source]
Circular Streets
Public API Methods using HTTP GET
-
List all circular streets for 2010
playaevents.burningman.com/api/0.2/2010/cstreet/
jQuery Circular Streets example [source]
Time Streets
Public API Methods using HTTP GET
-
List all time streets for 2009
playaevents.burningman.com/api/0.2/2009/tstreet/
jQuery Time Streets example [source]
Authentication
Some API methods require authentication, because they are either returning sensitive data or they are altering data. Each method that requires authentication is marked "Authentication required" above.
Authentication is done via a simple “signature"”, which is then appended to the querystring of the API url. We'll go into more detail below, but here is the basic scheme:
-
Find the URL you want to sign. For example, let's say you want to delete event #665. The API url for the DELETE call would be
playaevents.burningman.com/api/0.2/2011/event/665/
-
Strip off the domain name and any query arguments, so for this example we'd have
/api/0.2/2011/event/665/
- Get your API key. You must be authorized to use API functions, which you can do by using the contact page on playaevents.burningman.com, once approved, you can get the API key from your profile page at playaevents.burningman.com/accounts/profile/
- Make a random "seed" for signing. The easiest "seed" is to simply take the timestamp of today, expressed as seconds. Anything at all will be fine, but there are two caveats. First, the seed can't ever be reused, and second, it needs to be less than 40 characters.
-
Add your username to the querystring. For example, if my username was "example", the url to be signed would be:
/api/0.2/2011/event/665/?user=example
- Make a signature by taking an MD5 of the url, your seed, and your key, in that order. (code examples below)
-
Add the seed and your signature to the url. For example, if your seed was "1302229284" and your MD5 signature was "5de4fce4f3135424be0a63db8f3ef20c", your final url would look like this:
/api/0.2/2011/event/665/&user=example&seed=1302229284&sig=5de4fce4f3135424be0a63db8f3ef20c
- That's it. Call the url and if you are authorized, the action will be carried out. In our example, event #665 would be deleted. Note that it will only work once for that seed and signature.
Authentication Code Examples
PythonPython example code:
import hashlib
import time
import types
import urllib
import urlparse
def _add_query_param(query, param, val):
"""Add a querystring parameter to the url"""
last = '%s=%s' % (param, urllib.quote_plus(val))
if query:
return "%s&%s" % (query, last)
else:
return last
def _remove_query_param(query, param):
"""Removes a query param, leaving the querystring in order"""
parts = query.split('&')
look = "%s=" % param
for ix in range(len(parts)-1, -1, -1):
if parts[ix].startswith(look):
del parts[ix]
return '&'.join(parts)
def _replace_query_param(query, param, val):
"""Replaces a query param, leaving the querystring in order"""
parts = query.split('&')
look = "%s=" % param
for ix in range(0, len(parts)):
if parts[ix].startswith(look):
parts[ix] = "%s=%s" % (param, urllib.quote_plus(val))
break
return '&'.join(parts)
def sign_url(url, key, user=None, seed=None):
"""Sign an url.
Args:
url: An url to sign. It can have query parameters which will be preserved.
If there is no "seed" provided as a keyword arg, it will look in the
query params for it before finally simply giving up and using the
current timestamp as the seed.
key: a key to sign with
Kwargs:
user: a user to sign with
seed: An explicit seed string to use for signing.
Returns:
The same url, with its signature added to the querystring.
"""
origurl = url
parsed = urlparse.urlsplit(url)
query = parsed.query
qs = parse_qs(query)
if not seed:
# first look at query
if 'seed' in qs:
seed = qs['seed']
query = _remove_query_param(query,'seed')
else:
timestamp = datetime.datetime.now()
timestamp = time.mktime(timestamp.timetuple())
seed = str(int(timestamp))
log.debug('sign_url: no seed, using timestamp %s', seed)
if user is not None:
if 'user' in qs:
username = qs['user']
if type(username) is types.ListType:
username = username[0]
if username != user.username:
query = _replace_query_param(query, 'user', self.user.username)
else:
if 'user' in qs:
query = _remove_query_param(query, 'user')
url = urlparse.urlunsplit((parsed.scheme, parsed.netloc, parsed.path, query, parsed.fragment))
processor = hashlib.md5(work)
processor.update(seed)
processor.update(key)
sig = processor.hexdigest()
query = _add_query_param(query, 'seed', seed)
query = _add_query_param(query, 'sig', sig)
url = urlparse.urlunsplit((parsed.scheme, parsed.netloc, parsed.path, query, parsed.fragment))
return url
PHP
PHP Example code:
/**
* Sign an url for use by the Events API
*
* @param string $apiurl the url fragment to sign, it should not contain the scheme or server
* @param string $key the user key
* @param string $user the user name for the key
* @param array $apiatts array of options with key=value
* @param array $urlinfo the url of the originial gallery link as parsed by parse_url
* @return string url
*/
function gallery_sign_url($apiurl, $key, $user, &$apiatts, $urlinfo) {
$apiurl = str_replace('//', '/', $apiurl);
if (!empty($key) && !empty($user)) {
$apiatts[] = 'user=' . $user;
$apiurl .= '?' . implode('&',$apiatts);
$seed = time();
$n = rand(10e16, 10e20);
$seed .= base_convert($n, 10, 36);
$sig = md5($apiurl . $seed . $key);
$apiurl .= "&seed=$seed&sig=$sig";
}
elseif (count($apiatts) > 0) {
$apiurl .= '?' . implode('&',$apiatts);
}
$signed = $urlinfo['scheme'] . '://' . $urlinfo['host'];
if (!empty($urlinfo['port']) && $urlinfo['port'] <> 80) {
$signed .= ':' . $urlinfo['port'];
}
$signed .= $apiurl;
return $signed;
}

