The Plazes API (Pre-release)
Welcome to the documentation for the Plazes API. This is still pre-release and therefore subject to change!
Your questions, comments or suggestions are very welcome. Post to the plazesapi yahoo group if you want to share it with other developers, or send an email to support@plazes.com.
External information and projects around the Plazes API can be found at plazecamp on google code.
Any example in here can also be executed with ‘plazes.com’ replaced by ‘sandbox.plazes.com’. Instead of accessing the live plazes.com service it then runs against a copy of the data which is refreshed every couple of days and has no effect on the live plazes.com data. You can browse to http://sandbox.plazes.com to see the effects of your API calls.
Last modified: Jan 12th, 2008.
The Plazes API gives you the ability to interact with the Plazes service. Use the Plazes API to coordinate your activities with the people you trust, broadcast your location to the world, or to whom you trust.
Lookup Plazes within our database of Plazes based on your previous activities, the name, address or even the network your are using.
- Diving right in with ActiveResource
- Interesting URLs
- Walkthrough
- Compatibility with API updates
- Authentication and Authorization
- Collections
- Resources
- Users
- Plazes
- GET /plazes.xml
- POST /plazes.xml
- Plazes Categories
- GET /plazes/{id}.xml
- PUT /plazes/{id}.xml
- GET /plazes/{id}/comments.xml
- GET /plazes/{id}/pictures.xml
- Activities
- GET /activities.xml
- POST /activities.xml
- DELETE /activities/{id}.xml
- GET /activities/{id}.xml
- GET /users/{id}/activity.xml
- GET /users/{id}/activities.xml
- GET /users/{id}/future_activities.xml
- GET /users/{id}/past_activities.xml
- GET /plazes/{id}/activities.xml
- Authentication transfer
- Other formats
Diving right in with ActiveResource
Using ActiveResource (a Ruby client library for REST services) we can jump right in, create our first Activity and share this with others.
On the command line, install Ruby and RubyGems, then use RubyGems to install the latest version of ActiveResource with rubygems package management.
# sudo gem install --source http://gems.rubyonrails.com activeresource
Open your favorite editor and start a script that will prepare the base classes and site credentials. Replace {username} and {password} with your username and password:
#!/usr/bin/ruby
require 'rubygems'
gem 'activeresource', '>= 1.99.0'
require 'activeresource'
class PlazesResource < ActiveResource::Base
self.site = 'http://{username}:{password}@plazes.com'
end
class Activity < PlazesResource; end
class Plaze < PlazesResource; end
Now you can create your first activity:
activity = Activity.new(:status => 'Creating my first activity', :plaze => Plaze.new(:name => 'test'))
And give feedback if the creation worked, or show the errors that ActiveResource nicely packages up.
if activity.save
puts "find me here: http://plazes.com/activities/#{activity.id}"
else
puts activity.errors.full_messages
end
Interesting URLs
Here are some URLs that contain interesting information about the site. The notation of {id} implies that you should replace that with a valid ID.
Activities
- GET http://plazes.com/activities.xml
- All activities ordered descending by created_at
- POST http://plazes.com/activities.xml
- Create an activity owned by the authenticated user.
- GET http://plazes.com/activities/{id}.xml
- Detailed information about a specific activity
- DELETE http://plazes.com/activities/{id}.xml
- Remove one of your own activities, and all comments.
- GET http://plazes.com/plazes/{id}/activities.xml
- All activities of a Plaze ordered descending by created_at
- GET http://plazes.com/users/{id}/activities.xml
- All activities of a User ordered descending by created_at
- GET http://plazes.com/users/{id}/future_activities.xml
- Future activities of a User ordered ascending by scheduled_at
- GET http://plazes.com/users/{id}/past_activities.xml
- Past activities of a User ordered descending by scheduled_at
- GET http://plazes.com/users/{id}/activity.xml
- The single most relevant activity at request time, either in the recent past or near future for this user.
Users
- GET http://plazes.com/me.xml
- Details about the currently authenticated user, contains extra fields like number of unread messages.
- GET http://plazes.com/users/{id}.xml
- Details about a given user such as avatar URL and full_name.
Plazes
- GET http://plazes.com/plazes.xml
- Find the right plaze. Takes the query parameter q which is a text string that can be used to narrow your search. Ordered by relevancy to the search.
- GET http://plaze.com/plazes/{id}.xml
- Details about a given Plaze
Theory and Practice of the Plazes API
The Plazes API is based on REST (Representational State Transfer) that basically defines a Resource based approach to interacting with a service over HTTP using the HTTP methods to return specific content types. Resources are grouped together into Collections, which define meaningful organization, filtering or ordering of Resources.
HTTP methods
REST uses 4 HTTP methods that map to the verbs that you can use to interact with the resources in Plazes. These verbs represent the most common things you’d want to do.
Create, Read, Update and Delete
- Resource verb (HTTP method)
- Example
- Create (POST)
- POST http://plazes.com/activities
- Read (GET)
- GET http://plazes.com/activities/1
- Update (PUT)
- PUT http://plazes.com/activities/1
- Delete (DELETE)
- DELETE http://plazes.com/activities/1
HTTP request / content type
So using the HTTP method to describe the verb we wish, we still need to let Plazes know what content type the request and response contains.
To do this, append to the URL the format you wish to send or receive. Most often this will be +.xml+. Alternatively you can also send the HTTP request header ‘Accept: application/xml’.
The following examples use the curl command line utility and pure HTTP for creating, updating, reading and deleting an Activity. Starting with a quick tutorial of curl:
Authenticate with -u
curl -u bob:secret http://plazes.com/activities/100002.xml
Specify the HTTP method with -X
curl -u bob:secret -X DELETE http://plazes.com/activities/100002.xml
Send data with -d
curl -u bob:secret -X POST -H 'Content-Type: application/xml' \
http://plazes.com/activities.xml -d '
<activity>
<status>Tubberware!</status>
<plaze_id>12345</plaze_id>
</activity>'
Walkthrough
Create Request - Here we go! Going to get all my friends together and storm the mall in our bunny costumes.
curl -u bob:secret -X POST -H 'Content-Type: application/xml' \
http://plazes.com/activities.xml -d '
<activity>
<plaze_id>12345</plaze_id>
<status>Pink bunnies Flash Mob</status>
<scheduled_at type="datetime">2007-10-11T16:30:00Z</scheduled_at>
</activity>'
POST /activities.xml HTTP/1.1
<activity>
<plaze_id>12345</plaze_id>
<status>Pink bunnies Flash Mob</status>
<scheduled_at type="datetime">2007-10-11T16:30:00Z</scheduled_at>
</activity>
Create Response - Success. Now I know what to share with the world.
HTTP/1.1 201 Created Location: http://plazes.com/activities/100002
Read Request - Following the location header to transfer the server state to my client.
curl -u bob:secret -X GET http://plazes.com/activities/100002.xml GET /activities/100002.xml HTTP/1.1
Read Response - See how the non-mandatory fields have been filled out by the server.
HTTP/1.1 200 OK
Content-Type: application/xml
<activity>
<id type="integer">100002</id>
<user_id type="integer">4717</user_id>
<plaze_id type="integer">12345</plaze_id>
<status>Pink bunnies Flash Mob</status>
<device>web</device>
<scheduled_at type="datetime">2007-10-11T16:30:00Z</scheduled_at>
<created_at type="datetime">2007-10-01T14:35:01Z</created_at>
</activity>
Update Request - Oh, I found where the Plaze actually is, and need to put it on the map.
curl -u bob:secret -X PUT -H 'Content-Type: application/xml' \
http://plazes.com/plazes/12345.xml -d '
<plaze>
<latitude>47.618043</latitude>
<longitude>-122.201217</longitude>
</plaze>'
PUT /plazes/12345.xml HTTP/1.1
Content-Type: application/xml
<plaze>
<latitude>47.618043</latitude>
<longitude>-122.201217</longitude>
</plaze>
Update Response - Done!
HTTP/1.1 200 OK
Content-Type: application/xml
<plaze>
<id>12345</id>
<name>Bellevue Square Gardens</name>
<address>575 Bellevue Sq</address>
<zip_code>98004</zip_code>
<state>WA</state>
<city>Bellevue</city>
<country_code>US</country_code>
<has_free_wifi type="boolean">false</has_free_wifi>
<updated_at type="datetime">2001-01-01T00:00:00Z</updated_at>
<country>United States of America</country>
<category>shop</category>
<latitude type="float">-122.201217</latitude>
<longitude type="float">47.618043</longitude>
<link>http://bellevuesquare.com</link>
</plaze>
Delete Request - Great success, but we’re running from the mall cops now. Remove this resource completely. Even though we’re not expecting a body in the response, we let the server know that we are using the API by setting the format to xml.
curl -u bob:secret -X DELETE http://plazes.com/activities/100002.xml DELETE /activities/100002.xml HTTP/1.1
Delete Response - Success!
HTTP/1.1 200 OK
Compatibility with API updates
When new functionality is added to Plazes or changed, it may become useful to add attributes to the responses or possible inputs described here. So a call that previously returned:
<foo>
<bar>...</bar>
</foo>
may change later to return:
<foo>
<bar>...</bar>
<baz>...</baz>
</foo>
Client software should be built in a way that it does not break when attributes are added in this way.
Also new functionality may result in completely new collections and resources to be added later to this API.
Authentication and Authorization
Auth with the Plazes API is handled with HTTP Basic authentication using the Authorization header. (rfc2616)
Authentication
Determine who a user is.
To authenticate yourself against the Plazes API, include your normal username/password of your Plazes account.
Authorization
Determine what a user can do.
Every authenticated request is implicitly authorized to view and perform different actions on resources within Plazes.
Privacy
Plazes respects the privacy of its users and by doing so allows users to only make their activities available to people they trust. After you authenticate, your user account will be checked against the permissions that other users have granted when sharing their activity with you.
This means that 2 different users may see 2 different Activity collections, or one user will receive a 404 when reading one Activity and another user will receive a 200 when trying to read the same Activity.
Let’s say that User ‘mary’ with the ID 1234 only shares her Activities with people she trusts. User ‘bob’ is one user that ‘mary’ trusts.
This request will successfully return an empty collection. Note that there is no error here, it looks like we’re permitted to see her Activities, and that she hasn’t made any yet.
curl http://plazes.com/users/1234/activities.xml
Where when we authenticate as ‘bob’, we become authorized to see mary’s Activities.
curl -u 'bob:secret' http://plazes.com/users/1234/activities.xml
Forcing authentication
Lets say we wish to give a link to mary’s Activities to ‘cheezeshop’. We don’t know cheezeshop’s password, but know that cheezeshop is someone that mary trusts. We would then give cheezeshop a URL which would initiate HTTP authentication, so cheezeshop can enter her own password. With this extra query parameter, cheezeshop can directly put this URL in her Feed Reader and get a personalized collection of mary’s Activities.
http://plazes.com/users/1234/activities.xml?personalize=1
Collections
Above describes working with individual Resources. Grouped together, the Resources form collections. Collections have different meaning, ordering or inclusion of Resources depending on their definition. But all collections share the following:
- Consistent type - only Activities, only Plazes
- An offset starting at 0
Chunking
All collections are limited to a certain number of returned resources per request. If you want more results than received, you can request more. If you want all of the results then keep requesting with larger offsets until no results are returned. The default chunk size is 50 resources. Some collections may initally return fewer or more and that may change over time.
To receive a complete collection use the following algorithm:
- Start with an offset of 0
- Request a collection chunk from the offset
- If you receive results:
- Increment the offset by number of resources returned
- Repeat from step 2
- offset
- Zero based offset of the collection. The offset is used to request successive chunks of the collection and is determined by counting the elements returned from the previous chunk.
Resources
This is the reference of resources and collections. The notation of {id} indicates that a value must be supplied by you.
Note: there is no implicit meaning of the allocation of IDs. In your client application, you should consider +id+ or thing+_id+ fields as opaque.
Users
- GET /me.xml
- the User resource of the authenticated user
- GET /users.xml
- All Users ordered by relevancy (search interface)
- GET /users/{id}.xml
- User resource
Users are the people part of Plazes. Users have a screen name ‘name’ and a full name ‘full_name’. To create, update or delete users, you must use the web site.
GET /me.xml
Returns the user resource of the authenticated user. Use the ID of this resource to get at your dependent collections or resources.
If the user could not be authenticated, then HTTP authentication will begin with a status code of 401.
Extra attributes on the resource returned
- unread_message_count
- number of unread Plazes messages in your inbox
curl -u bob:secret http://plazes.com/me.xml
HTTP/1.1 200 OK
<user>
<id>4717</id>
<updated_at type="datetime">2006-10-11T19:11:20Z</updated_at>
<name>bob</name>
<full_name>Dr. Shoes</full_name>
<avatar_url>http://plazes.com/pictures/dfd01c7760e41c9c572339cf7246aef5-medium.jpg</avatar_url>
<unread_message_count type="integer">1</unread_message_count>
</user>
GET /users.xml
User search. Returns a users in ascending order by relevancy to the search query.
- q
- The search query. This will be split on spaces and each term will be searched inclusively in the text fields of all users.
curl -u bob:secret http://plazes.com/users.xml?q=til+singer
HTTP/1.1 200 OK
<users>
<user>
<created_at type="datetime">2004-08-09T16:17:21Z</created_at>
<full_name>Tilmann Singer</full_name>
<id>266</id>
<updated_at type="datetime">2007-12-04T15:27:25Z</updated_at>
<name>til</name>
<avatar_url>http://plazes.com/pictures/92e741ffa98fe66127dd23ea211be611-medium.jpg</avatar_url>
</user>
...
</users>
GET /users/{id}.xml
The canonical resource of a given user.
curl -u bob:secret http://plaze.com/users/{id}.xml
HTTP/1.1 200 OK
<user>
<id>4717</id>
<updated_at type="datetime">2006-10-11T19:11:20Z</updated_at>
<name>bob</name>
<full_name>Dr. Shoes</full_name>
<avatar_url>http://plazes.com/pictures/dfd01c7760e41c9c572339cf7246aef5-medium.jpg</avatar_url>
</user>
Plazes
- GET /plazes.xml
- All Plazes (search/suggestion interface) ordered by descending relevancy
- POST /plazes.xml
- Create a plaze
- GET /plazes/{id}.xml
- Plaze resource
- PUT /plazes/{id}.xml
- Update a plaze
Plazes are where people can be. Plazes are most interesting when working with Activities. They are named, shareable, public locations. They must have a city and country, and can have all kinds of stuff associated with them to make them more interesting on the web.
GET /plazes.xml
Finding the right Plaze is the first step to start for many uses of the API. To create an Activity, you must either find a Plaze or let the feeling-lucky mode of Activity creation find one for you. An Activity isn’t very interesting unless you know where to meet.
This collection of Plazes is ordered on relevancy to the search query(ies).
Query parameters:
- q
- The textual terms to search for in the following fields: name, address, zip_code, city, state (and full state name), country_code (and country names) category, tags
- mac_address
- If you know the network machine address of your subnet’s gateway, you can use this to find Plazes that have previously been created with the Plazer. mac_address should look something like: ff:23:50:1c:34:60
Example:
curl -u bob:secret http://plazes.com/plazes.xml?q=cheese+shop
HTTP/1.1 200 OK
<plazes>
<plaze>
<id>21</id>
<name>Cheese Galore</name>
<address>Torstrasse 11</address>
<zip_code>10425</zip_code>
<state></state>
<city>Berlin</city>
<country_code>DE</country_code>
<has_free_wifi type="boolean">false</has_free_wifi>
<updated_at type="datetime">2001-01-01T00:00:00Z</updated_at>
<country>Germany</country>
<category>shop</category>
<latitude type="float">52.537995812247</latitude>
<longitude type="float">13.412426179325</longitude>
<link>http://plazes.com</link>
<photo_url>http://plazes.com/photos/2107b4468b4795c69288fdc9961a3415-thumbnail.jpg</photo_url>
</plaze>
<plaze>
...
</plaze>
</plazes>
If no results are found, an empty collection is returned
HTTP/1.1 200 OK <plazes> </plazes>
POST /plazes.xml
Creating a Plaze requires a name, city and country at a minimum. But because Plazes are all about location, try to also include a latitude and longitude.
curl -u bob:secret -X POST -H 'Content-Type: application/xml' \
http://plazes.com/plazes.xml -d '
<plaze>
<name>Better Stuff</name>
<city>Berlin</city>
<country>Germany</country>
</plaze>'
HTTP/1.1 201 Created
Location: http://plazes.com/plazes/2000012
If the Plaze could not be created because there is some missing information such as city or country_code 422 will be returned:
HTTP/1.1 422 Unprocessable
<errors>
<error>Country code is missing</error>
</errors>
Plazes Categories
Valid entities for category:
- office
- home
- restaurant
- airport
- railway_station
- other
- hotel
- conference
- university
- bar
- coffee_shop
- club
- museum
- theater
- movie_theater
- shop
- stadium
- landmark
GET /plazes/{id}.xml
The canonical Plaze.
curl -u bob:secret http://plazes.com/plazes/{id}.xml
HTTP/1.1 200 OK
<plaze>
<id>2000012</id>
<name>Better Stuff</name>
<city>Berlin</city>
<address></address>
<zip_code></zip_code>
<state></state>
<country_code>DE</country_code>
<country>Germany</country>
<has_free_wifi type="boolean">false</has_free_wifi>
<category>other</category>
<link>http://plazes.com</link>
<photo_url>http://plazes.com/photos/2107b4468b4795c69288fdc9961a3415-thumbnail.jpg</photo_url>
<latitude>8.123456</latitude>
<longitude>51.123456</longitude>
<updated_at type="datetime">2001-01-01T00:00:00Z</updated_at>
<created_at type="datetime">2001-01-01T00:00:00Z</created_at>
</plaze>
PUT /plazes/{id}.xml
Update a Plaze with new fields.
curl -u bob:secret -X PUT -H 'Content-Type: application/xml' \
http://plazes.com/plazes/{id}.xml -d '
<plaze>
<name>Even Better Stuff</name>
</plaze>'
HTTP/1.1 200 OK
<plaze>
<id>2000012</id>
<name>Even Better Stuff</name>
<city>Berlin</city>
<address></address>
<zip_code></zip_code>
<state></state>
<country_code>DE</country_code>
<country>Germany</country>
<has_free_wifi type="boolean">false</has_free_wifi>
<category>other</category>
<link>http://plazes.com</link>
<photo_url>http://plazes.com/photos/2107b4468b4795c69288fdc9961a3415-thumbnail.jpg</photo_url>
<latitude>8.123456</latitude>
<longitude>51.123456</longitude>
<updated_at type="datetime">2001-01-01T00:00:00Z</updated_at>
<created_at type="datetime">2001-01-01T00:00:00Z</created_at>
</plaze>
If the Plaze could not be updated, because a required field is missing or malformed an error 422 is returned.
HTTP/1.1 422 Unprocessable
<errors>
<error>Name is missing</error>
<error>City is missing</error>
<error>Country code is missing</error>
</errors>
GET /plazes/{id}/comments.xml
All comments on a plaze, ordered by descending creation time.
curl http://plazes.com/plazes/17778/comments.xml
<comments>
<comment>
<body>Great job on the new Plazes, people!</body>
<created_at type="datetime">2007-05-30T13:38:24Z</created_at>
<id>12345</id>
<user>
<created_at type="datetime">2007-05-21T13:25:37Z</created_at>
<full_name>Dr. Shoes</full_name>
<id>313131</id>
<updated_at type="datetime">2007-10-21T12:00:39Z</updated_at>
<name>drshoes</name>
<avatar_url>http://plazes.com/pictures/5af2123e1e00a7fd3a3123fabc8b1dc94-medium.jpg</avatar_url>
</user>
</comment>
...
</comments>
GET /plazes/{id}/pictures.xml
All pictures on a plaze, ordered by descending upload time.
curl http://plazes.com/plazes/17778/pictures.xml
<pictures>
<picture>
<created_at type="datetime">2007-05-24T12:06:50Z</created_at>
<id>12346</id>
<picture_url>http://plazes.com/pictures/7fb2aef587378f8b1fce64eb0408874c-medium.jpg</picture_url>
<user>
<created_at type="datetime">2007-05-05T19:13:48Z</created_at>
<full_name>Some One</full_name>
<id>21345</id>
<updated_at type="datetime">2007-06-25T11:12:10Z</updated_at>
<name>someone</name>
<avatar_url>http://plazes.com/pictures/1290abc23da2ea2399e920cae7bcff6c-medium.jpg</avatar_url>
</user>
</picture>
...
</pictures>
Activities
- GET /activities.xml
- All Activities ordered by descending creation time
- POST /activities.xml
- Create a activity
- PUT /activities/{id}.xml
- Update a activity
- DELETE /activities/{id}.xml
- I never will be/was here
- GET /activities/{id}.xml
- Single activity
- GET /users/{id}/activity.xml
- The current activity of a user
- GET /users/{id}/activities.xml
- Activities of a User - ordered by descending creation time
- GET /users/{id}/past_activities.xml
- Activities of a User before now
- GET /users/{id}/future_activities.xml
- Activities of a User after now
- GET /plazes/{id}/activities.xml
- Activities of a Plaze - ordered by descending creation time
Activities are the most interesting resources Plazes can offer. An Activity is a record of a User at Plaze at a given point in time doing a specific thing either in the future, in which the Activity is scheduled for a specific time or a record of an actual or planned presence at a Plaze. Activities can be created through the Web, SMS, Plazer application and the API. Creating an Activity is like saying "I’m here now", "I plan to be here" or "I was here some time in the past".
Privacy of Activities are honored here which means different collections could be returned for different users. If a user only publishes Activities to trustees, and the authenticated user is not a trustee of a user, then the authenticated user will not see the Activity.
Timezones
Activities have 2 times. The time that they were created, and the time that they are scheduled. The created_at time is always in UTC where the scheduled_at time is the local time of the the Plaze, identified by activity.plaze.timezone.
When creating or updating an Activity, the scheduled_at time can be accepted with a time zone. This time will be converted to UTC, then the time zone offset of the Plaze of the activity will be applied. In practice, this means that if you wish to schedule an activity, pass the scheduled_at time in the time zone of the Plaze which is most likely your local timezone.
GET /activities.xml
The collection of all activities within the site, ordered descending by created_at. Ordering by this field allows the same collection to be used as a news feed.
This collection includes the User and Plaze resources for each activity.
curl -u bob:secret http://plazes.com/activities.xml
HTTP/1.1 200 OK
<activities>
<activity>
<id type="integer">3001</id>
<user_id type="integer">4717</user_id>
<plaze_id type="integer">87873</plaze_id>
<status>Thinking about pink elephants</status>
<device>sms</device>
<scheduled_at type="datetime">2007-02-01T14:35:01-09:00</scheduled_at>
<created_at type="datetime">2007-02-01T14:35:01Z</created_at>
<user>
<id>4717</id>
<name>seant</name>
<full_name>Sean Treadway</full_name>
<avatar_url>http://plazes.com/pictures/dfd01c7760e41c9c572339cf7246aef5-medium.jpg</avatar_url>
</user>
<plaze>
<address>Monbijouplatz 5</address>
<category>office</category>
<city>BERLIN</city>
<country_code>DE</country_code>
<has_free_wifi type="boolean">false</has_free_wifi>
<id>87873</id>
<link>http://plazes.com/plazes/87873</link>
<name>Plazes HQ</name>
<state></state>
<timezone>Europe/Berlin</timezone>
<updated_at type="datetime">2007-10-19T15:26:58Z</updated_at>
<zip_code>10178</zip_code>
<latitude type="float">52.5234803915622</latitude>
<longitude type="float">13.3988088369369</longitude>
<country>Germany</country>
<picture_url>http://assets.plazes.com/pictures/f3b2a36c5dfe21300b487cb1242df212-medium.jpg</picture_url>
</plaze>
</activity>
<activity>
<id type="integer">13506</id>
<user_id type="integer">4717</user_id>
<plaze_id type="integer">85127</plaze_id>
<status>Visiting friends</status>
<scheduled_at>2007-02-01T15:00:00+01:00</scheduled_at>
<device>web</device>
<created_at type="datetime">2007-02-01T14:00:00Z</created_at>
<user>
<id>4717</id>
<name>seant</name>
<full_name>Sean Treadway</full_name>
<avatar_url>http://plazes.com/pictures/dfd01c7760e41c9c572339cf7246aef5-medium.jpg</avatar_url>
</user>
<plaze>
<address>1429 1ST AVENUE</address>
<category>other</category>
<city>SEATTLE</city>
<country_code>US</country_code>
<has_free_wifi type="boolean">false</has_free_wifi>
<id>85127</id>
<link>http://www.MyOmniOnMe.com</link>
<name>OmniZone108 - Pike Place Market</name>
<state></state>
<timezone>America/Los_Angeles</timezone>
<updated_at type="datetime">2007-07-15T20:49:57Z</updated_at>
<zip_code>98101</zip_code>
<latitude type="float">47.6084632868383</latitude>
<longitude type="float">-122.339909076691</longitude>
<country>United States</country>
<picture_url>http://plazes.com/pictures/0eff73614454e151e90d26f2f33be646-medium.jpg</picture_url>
</plaze>
</activity>
<activity>
...
</activity>
</activities>
POST /activities.xml
Create a new activity.
Every activity must have a Plaze. You can either specify the plaze explicitly by including an existing plaze_id in the create request, or you send one or more plaze attributes which will trigger a search and will use the first best match as plaze of the activity (you could call that the feeling-lucky-mode). It will try to find a plaze that matches the given data. If none found, it will create a new plaze if sufficient data was given. If neither lookup nor plaze creation succeeds then the activity creation will fail.
To associate a mac_address to an Activity to be able to find Plazes that share Activities at the same mac_address then add that field if you know it. The mac_address is optional during Activity creation.
The user_id field will be ignored, and will always be the authenticated user.
curl -u bob:secret -X POST -H 'Content-Type: application/xml' \
http://plazes.com/activities.xml -d '
<activity>
<plaze_id>87873</plaze_id>
<status>Checking in for the first time!</status>
<mac_address>62:6f:62:42:4f:42</mac_address>
</activity>'
HTTP/1.1 201 Created
Location: http://plazes.com/activities/1234567
If the Activity could not be created, because a required field is missing or malformed an error 422 is returned.
HTTP/1.1 422 Unprocessable
<errors>
<error>Activity must have a Plaze</error>
</errors>
You have a couple options for creating an activity without already knowing the Plaze. You can search based on the name, or mac_address.
scheduled_at
The scheduled_at attribute of an activity specifies when this activity is planned to take place, or when it took place. When left empty on creating an activity, scheduled_at defaults to now.
When scheduled_at is specified then it will be stored as UTC, but converted to the timezone of its plaze on display.
As of now, any timezone information appended to the time is ignored and the value is interpreted as UTC. (This behaviour may change in the future to actually convert to UTC when a timezone offset was specified.)
To create an activity with a time in the timezone of the plaze, you can set scheduled_at_is_plaze_local:
curl -u bob:secret -X POST -H 'Content-Type: application/xml' \
http://plazes.com/activities.xml -d '
<activity>
<scheduled_at>2008-02-01T11:00:00</scheduled_at>
<scheduled_at_is_plaze_local>1</scheduled_at_is_plaze_local>
<plaze_id>1234</plaze_id>
</activity>'
Create activity without plaze_id
Search with the name of the Plaze:
curl -u bob:secret -X POST -H 'Content-Type: application/xml' \
http://plazes.com/activities.xml -d '
<activity>
<status>Checking in for the first time!</status>
<plaze>
<name>Test</name>
</plaze>
</activity>'
HTTP/1.1 201 Created
Location: http://plazes.com/activities/1234567
Search with a mac_address:
curl -u bob:secret -X POST -H 'Content-Type: application/xml' \
http://plazes.com/activities.xml -d '
<activity>
<status>Checking in for the first time!</status>
<mac_address>62:6f:62:42:4f:42</mac_address>
</activity>'
HTTP/1.1 201 Created
Location: http://plazes.com/activities/1234567
Note that the mac_address element is a direct child of the activity element, not of the plaze element.
Search with both name, city, country_code and mac_address:
curl -u bob:secret -X POST -H 'Content-Type: application/xml' \
http://plazes.com/activities.xml -d '
<activity>
<status>Checking in for the first time!</status>
<mac_address>62:6f:62:42:4f:42</mac_address>
<plaze>
<name>Test</name>
<city>Berlin</city>
<country_code>DE</country_code>
</plaze>
</activity>'
HTTP/1.1 201 Created
Location: http://plazes.com/activities/1234567
Specifying a device
On the Plazes website and in the feeds there is often a little text next to an activity like this: ‘created via plazer’. If an activity was created by a POST to /activities with a content type of html, then the device will be set to ‘web’. If the content type is not html then the device depends on the User-Agent http header. If the User-Agent matches a known client then it will be set to the short string identifying this client, otherwise device will be empty.
Right now there is one known client for testing purposes. Send a User-Agent that contains the string ‘device: api’ with your activity creation and the activity will show up as ‘created via api’.
Please send us an email if you wish to have your client recognized by Plazes. The short identifier must fit in the small space on the website and is therefore limited to 8 characters, lowercase ascii chars only.
DELETE /activities/{id}.xml
To remove a record that you’ve been at a specific Plaze, saying "I’ve never been there", you need to delete the Activity by the Activity ID.
The authenticated user must also be the user referenced by the user_id field of the Activity to be successful.
curl -u bob:secret -X DELETE http://plazes.com/activities/1234567.xml HTTP/1.1 200 OK
If you are not the same user as the one identified by user_id of that Activity, an error 403 will be returned.
curl -u mary:lamb -X DELETE http://plazes.com/activities/1234567.xml HTTP/1.1 403 Not Authorized
GET /activities/{id}.xml
Once an Activity is created, it maintains its ID through its lifetime.
curl -u bob:secret http://plazes.com/activities/1234567.xml
HTTP/1.1 200 OK
<activity>
<id>1234567</id>
<user_id>4717</user_id>
<plaze_id>87873</plaze_id>
<status>Collecting memories</status>
<scheduled_at>2007-10-11T08:13:00-05:00</scheduled_at>
<created_at type="datetime">2007-10-11T13:13:00Z</scheduled_at>
</activity>
Returns 404 if the Activity is not found or if you are not authorized to view it.
HTTP/1.1 404 Not Found
GET /users/{id}/activity.xml
The most relevant activity for this user. This is the activity that is featured on the user profile page and will be the closest activity in time from now, even if its in the future.
Include the Plaze dependent resource.
<activity>
<id>1234568</id>
<user_id>4717</user_id>
<plaze_id>87873</plaze_id>
<status>Making memories</status>
<scheduled_at type="datetime">2007-11-25T14:13:00+01:00</scheduled_at>
<created_at type="datetime">2007-10-11T13:13:00Z</created_at>
<plaze>
<address>Monbijouplatz 5</address>
<category>office</category>
<city>BERLIN</city>
<country_code>DE</country_code>
<has_free_wifi type="boolean">false</has_free_wifi>
<id>87873</id>
<link>http://plazes.com/plazes/87873</link>
<name>Plazes HQ</name>
<state></state>
<timezone>Europe/Berlin</timezone>
<updated_at type="datetime">2007-10-19T15:26:58Z</updated_at>
<zip_code>10178</zip_code>
<latitude type="float">52.5234803915622</latitude>
<longitude type="float">13.3988088369369</longitude>
<country>Germany</country>
<picture_url>http://assets.plazes.com/pictures/f3b2a36c5dfe21300b487cb1242df212-medium.jpg</picture_url>
</plaze>
</activity>
Note that depending on their trust status, two different viewers may see a different activity.
Returns 404 if the user is not found or the user has no activities that you are authorized to view.
HTTP/1.1 404 Not Found
GET /users/{id}/activities.xml
All the Activities for a user ordered by descending created_at. Note in this collection, the user_id will be the same for all resources.
The Plaze resource will be included and plaze id will match the activity plaze_id.
curl -u bob:secret http://plazes.com/users/1234567/activities.xml
HTTP/1.1 200 OK
<activities>
<activity>
<id>1234568</id>
<user_id>4717</user_id>
<plaze_id>87873</plaze_id>
<status>Making memories</status>
<scheduled_at type="datetime">2007-11-25T14:13:00+01:00</scheduled_at>
<created_at type="datetime">2007-10-11T13:13:00Z</created_at>
<plaze>
<address>Monbijouplatz 5</address>
<category>office</category>
<city>BERLIN</city>
<country_code>DE</country_code>
<has_free_wifi type="boolean">false</has_free_wifi>
<id>87873</id>
<link>http://plazes.com/plazes/87873</link>
<name>Plazes HQ</name>
<state></state>
<timezone>Europe/Berlin</timezone>
<updated_at type="datetime">2007-10-19T15:26:58Z</updated_at>
<zip_code>10178</zip_code>
<latitude type="float">52.5234803915622</latitude>
<longitude type="float">13.3988088369369</longitude>
<country>Germany</country>
<picture_url>http://assets.plazes.com/pictures/f3b2a36c5dfe21300b487cb1242df212-medium.jpg</picture_url>
</plaze>
</activity>
<activity>
...
</activity>
<activity>
...
</activity>
</activities>
GET /users/{id}/future_activities.xml
The stream of activities of a specific user starting from now and ascending into the future ordered by scheduled_at time.
Includes the Plaze dependent resources.
To get the next activity, set the limit to 1.
curl -u bob:secret http://plazes.com/users/{id}/future_activities.xml?limit=1
HTTP/1.1 200 OK
<activities>
<activity>
<id>1234567</id>
<user_id>4717</user_id>
<plaze_id>87873</plaze_id>
<status>Collecting memories</status>
<scheduled_at type="datetime">2007-10-11T14:13:00+01:00</scheduled_at>
<created_at type="datetime">2007-10-11T13:13:00Z</created_at>
<plaze>
<address>Monbijouplatz 5</address>
<category>office</category>
<city>BERLIN</city>
<country_code>DE</country_code>
<has_free_wifi type="boolean">false</has_free_wifi>
<id>87873</id>
<link>http://plazes.com/plazes/87873</link>
<name>Plazes HQ</name>
<state></state>
<timezone>Europe/Berlin</timezone>
<updated_at type="datetime">2007-10-19T15:26:58Z</updated_at>
<zip_code>10178</zip_code>
<latitude type="float">52.5234803915622</latitude>
<longitude type="float">13.3988088369369</longitude>
<country>Germany</country>
<picture_url>http://assets.plazes.com/pictures/f3b2a36c5dfe21300b487cb1242df212-medium.jpg</picture_url>
</plaze>
</activity>
</activities>
GET /users/{id}/past_activities.xml
The stream of activities starting from now and decending into the past ordered by scheduled_at time.
Includes the Plaze dependent resources. user_id will be the same for all activities.
To get the latest activity, set the limit to 1.
curl -u bob:secret http://plazes.com/users/{id}/past_activities.xml?limit=1
HTTP/1.1 200 OK
<activities>
<activity>
<id>1234567</id>
<user_id>4717</user_id>
<plaze_id>87873</plaze_id>
<status>Collecting memories</status>
<scheduled_at type="datetime">2007-10-11T14:13:00+01:00</scheduled_at>
<created_at type="datetime">2007-10-11T13:13:00Z</created_at>
<plaze>
<address>Monbijouplatz 5</address>
<category>office</category>
<city>BERLIN</city>
<country_code>DE</country_code>
<has_free_wifi type="boolean">false</has_free_wifi>
<id>87873</id>
<link>http://plazes.com/plazes/87873</link>
<name>Plazes HQ</name>
<state></state>
<timezone>Europe/Berlin</timezone>
<updated_at type="datetime">2007-10-19T15:26:58Z</updated_at>
<zip_code>10178</zip_code>
<latitude type="float">52.5234803915622</latitude>
<longitude type="float">13.3988088369369</longitude>
<country>Germany</country>
<picture_url>http://assets.plazes.com/pictures/f3b2a36c5dfe21300b487cb1242df212-medium.jpg</picture_url>
</plaze>
</activity>
</activities>
GET /plazes/{id}/activities.xml
The collection of Activities of Users at this Plaze ordered by descending created_at. The plaze_id in these Activities will always be the same as the ID in the URL.
The user of each activity will be included in each of these results and the user id will match the activity’s user_id attribute.
curl -u bob:secret http://plazes.com/plazes/{id}/activities.xml
HTTP/1.1 200 OK
<activities>
<activity>
<id>1234567</id>
<user_id>4717</user_id>
<plaze_id>87873</plaze_id>
<status>Collecting memories</status>
<scheduled_at type="datetime">2007-10-11T13:13:00Z</scheduled_at>
<created_at type="datetime">2007-10-11T13:13:00Z</created_at>
<user>
<id>4717</id>
<name>seant</name>
<full_name>Sean Treadway</full_name>
<avatar_url>http://plazes.com/pictures/dfd01c7760e41c9c572339cf7246aef5-medium.jpg</avatar_url>
</user>
</activity>
<activity>
...
</activity>
</activities>
Authentication transfer
- POST /sessions.xml
- Without username/password in the body should start an HTTP authorization attempt (401/403/200)
- GET /sessions/{id}/{redirect path}
- Transfer the authenticated session to a different agent with a cookie
Sometimes you need to open a link in a web browser authenticated as the same user that your application is using. In this case, you don’t want the user to have to reauthenticate to view the link you are sending them to within Plazes.
The Plazes website uses cookie based sessions to maintain authentication state. So to transfer authentication from pure HTTP to a cookie, you must first create a session, then tell Plazes that you would like that session to be used for a given URL.
POST /sessions.xml
This POST doesn’t take a body, only the credentials that are passed in the HTTP headers. It creates a Session that contains the HTTP authenticated user that can be used later.
curl -u bob:secret -X POST http://plazes.com/sessions.xml -d ''
HTTP/1.1 201 Created
<session>
<id>2107b4468b4795c69288fdc9961a3415</id>
</session>
Return 401 if no credentials are provided
HTTP/1.1 401 Unauthorized
Return 403 if the credentials could not be verified.
HTTP/1.1 403 Not Authorized
GET /sessions/{id}/{redirect path}
When you want to load a Plazes URL with the authenticated user, request the path with the ID of the newly created session and the remaining should be the actual path you wish load in the browser.
For example, after you created a session and wish to show http://plazes.com/messages, request this URL:
GET http://plazes.com/sessions/2107b4468b4795c69288fdc9961a3415/messages
The result will be a redirect and a Set-Cookie header.
HTTP/1.1 302 Moved Location: http://plazes.com/messages Set-Cookie: _session_id=2107b4468b4795c69288fdc9961a3415; path=/
Other formats
iCal
The public activities of a user are also available in iCal format at the following location:
GET http://plazes.com/users/{id}/activities.ics
It is sorted descending by scheduled_at. Currently the chunksize is 100 items. Subsequent chunks can be retrieved by specifying the optional offset parameter as described in Chunking.
Currently there is no iCal export that includes private activities.
Atom Feeds
Plazes currently provides these atom feeds for activity collections:
Activities of the authenticated user and friends:
GET http://plazes.com/activities/related.atom
Activities of a user:
GET http://plazes.com/users/{id}/activities.atom
GET http://plazes.com/users/{id}/activities.atom?personalize=1
Activities at a plaze:
GET http://plazes.com/plazes/{id}/activities.atom
GET http://plazes.com/plazes/{id}/activities.atom?personalize=1
Activities of a group:
GET http://plazes.com/groups/{id}/activities.atom
GET http://plazes.com/groups/{id}/activities.atom?personalize=1
See also Forcing Authentication
Microformats
Plazes also provides structured data in the form of microformats. However, this should not be seen as part of the API but rather as an extension to the html representation and subject to change along with the html representation. Thus it is not further documented here.
Plazes