Right Plaze, Right Time: Plazes




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

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:

  1. Start with an offset of 0
  2. Request a collection chunk from the offset
  3. If you receive results:
    1. Increment the offset by number of resources returned
    2. 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.

Diagram_session_transfer

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.


Login
Forgot Your Password?
Lost password
Back to login

© 2004-2008 Plazes AG