API Documentation
- The v2 API introduces a number of new features that were not available in the v1 API, including:
- Full read/write access to the history
- Private feeds
- A user management API
It also modifies the XML and JSON data formats in order to make them more consistent and to allow for more advanced functionality such as history.
General information about the API
A hierarchy of data types is used to represent data in the Pachube system: Feed >> Datastream >> Datapoint.
Environment (aka 'feed')
An 'environment' is a context-specific collection of measured data, often at a particular geolocation, defined by the creator of the environment and measured by sensors and devices. The term encompasses both physical entities such as a room, a mobile device, a building or a forest; and virtual entities such as a Second Life model, server bandwidth monitoring, etc. A Pachube 'feed' is the data representation of an environment and its datastreams. Its metadata can optionally specify whether it is physical or virtual, fixed or mobile, indoor or outdoor, etc.
Datastream
A datastream represents an individual sensor or measuring device/script within an environment. Every datastream must have a unique (within the environment) alphanumeric ID. It can also specify 'units' (e.g. 'watts') as well as user-defined 'tags' (e.g. 'fridge_energy').
Datapoint
A datapoint represents a single value of a datastream at a specific point in time. It is simply a key value pair of a timestamp and the value at that time.
Example: You wire up a hallway ('environment') with temperature, humidity and CO2 sensors ('datastreams'). You create a Pachube feed titled 'My Hallway', with three datastreams where the IDs could be: 'temperature', 'humidity' and 'CO2'; which might be tagged 'thermal,non-contact', 'capacitive, SHT21' and 'MG811' respectively; and have units 'Celsius', '%RH' and 'ppm'. Individual datapoints at a point in time might be '23.2', '34' and '3820' respectively.
Versions
There are currently two versions of the API active. Where possible you should use the most recent version available. We will endeavour to support all versions of the API as far as possible, but the most advanced functionality is unlikely to be backported to previous versions.
- Documentation for version 2, base URL: http://api.pachube.com/v2/* (released Aug 2010 - recommended).
- Documentation for version 1, base URL: http://api.pachube.com/v1/* (released Feb 2008 - deprecated).
Note: For legacy compatibility, the v1 API will remain available at http://www.pachube.com/api/* but usage should be switched over to use the base URL noted above as soon as possible.
Versioning the API enables you to lock your application to a specific API version. This means that the only changes we will make are:
- Adding new features whilst leaving the existing ones untouched
- Fixes which do not affect backwards compatibility
- Incrementing the format version numbers as required to accommodate any minor changes
JSON and XML formats both have version numbers included as part of their structure. This enables you either to specify a particular format for consistency or to verify what format the document is represented in.
HTTP-based & RESTful
The Pachube API is currently entirely based on HTTP requests, and conforms to the design principles of Representational State Transfer (REST). See this article for an extensive discussion about Pachube as a 'real-world instantiation of a RESTful interface for smart objects'.
The three main data types are represented hierarchically in the URL in the same way they are related, i.e. Environment >> Datastream >> Datapoint. RESTful access uses the HTTP verbs to determine which action to make on a particular data object:
- GET : Retrieves the current state of the object
- PUT : Sets the current state of the object
- POST : Creates a new object
- DELETE : Deletes the object
HTTP Status Codes
The Pachube API attempts to return appropriate HTTP status codes (see http://en.wikipedia.org/wiki/List_of_HTTP_status_codes) for every request.
Common status codes include:
- 200 OK: request processed successfully.
- 401 Not Authorized: either you need to provide authentication credentials, or the credentials provided aren't valid.
- 403 Forbidden: Pachube understands your request, but refuses to fulfill it. An accompanying error message should explain why.
- 404 Not Found: either you're requesting an invalid URI or the resource in question doesn't exist (eg. no such feed).
- 422 Unprocessable Entity: Pachube was unable to create a feed because the EEML/JSON was not complete/valid (e.g. it didn't include a "title" element).
- 500 Internal Server Error: Something went wrong... Please post to the forum about it and we will investigate.
- 503 No server error: usually occurs when there are too many requests coming into Pachube - if you get this from an API request then the error message will be returned in XML in the response.
Alternative PUT and DELETE requests
Not all HTTP clients are able to make PUT or DELETE requests (e.g. web browsers). In order to work around this limitation, it is possible to send a POST request with a "_method" parameter, e.g.
- POST to http://api.pachube.com/v2/feeds/504/datastreams/0.xml?_method=put will simulate a PUT
- POST to http://api.pachube.com/v2/feeds/504/datastreams/0.xml?_method=delete will simulate a DELETE
Feeds: manual vs. automatic & frozen vs. live
Environment feeds fall into one of two types: manual and automatic.
Manual feeds are those where the environment or device 'pushes' updates, usually via a PUT request. This is often done on a timed interval, on value-change or at some other significant moment (e.g. upon button press) and tend to be environments that sit behind a firewall or that are too low-powered to sustain a fully functioning server.
Automatic feeds, on the other hand, are those where the environment or device is able to serve data on request: Pachube automatically 'pulls' data from them either every 15 minutes or whenever another client requests it (whichever is the more frequent).
The status of a feed can be either live or frozen which mean slightly different things depending on the feed type:
- manual
- live means that the remote environment or device manually updated Pachube (i.e. 'pushed') with its data in the last 15 minutes.
- frozen means that it was last updated more than 15 minutes ago.
- automatic
- live means that Pachube has successfully retrieved data (i.e. 'pulled') from the remote environment or device in the last 15 minutes.
- frozen means that either it has not retrieved data in the last 15 minutes or that the last time it attempted to retrieve data (within the last 15 minutes) it was unsuccessful.
Security - SSL/HTTPS
Industry-standard HTTPS/SSL secure access is available for all authenticated methods, by replacing http with https in requests. All accounts have access to this functionality.
Authentication
API keys are used to control access to the resources via the API. They can be sent using one of two methods: as a request header or as a parameter in the request URL (with the former preferred for security reasons).
Using an HTTP header: This is the recommended method of sending your API key because, whilst still not secure if sent over an unencrypted connection, it is less likely to be logged as part of the URL:
X-PachubeApiKey: YOUR_API_KEY_HEREAs a request parameter:
http://api.pachube.com/v2/feeds?key=YOUR_KEY_HERE
Thus, sample GET requests may look like either:
GET /v2/feeds/504.xml HTTP/1.1 Host: api.pachube.com X-PachubeApiKey: ENTER_YOUR_PACHUBE_KEY_HERE
or:
GET /v2/feeds/504.xml?key=ENTER_YOUR_PACHUBE_KEY_HERE HTTP/1.1 Host: api.pachube.com
Additionally, it is possible to use basic authentication to identify yourself to the API service, however it is recommended to use API keys rather than basic auth if you are embedding your credentials in an application, otherwise there is a risk to your password.
Accounts & feature availability
To use Pachube's API you need a Pachube account. Sign up here: http://www.pachube.com/signup.
Feature availability and limits depend on account type, so not all methods will be available to all users. Refer to the subscriptions panel of your control panel (available at http://www.pachube.com/users/<your_username>/subscriptions for your current feature availability.
Rate limit
API usage is rate limited and this rate is determined by the account type of the user making requests. While the API rate limit is expressed in 'requests per minute' the calculation is averaged over 3 minutes. Currently the rate limit is 100 requests per minute.
If your application exceeds this rate, it will be unable to make any successful requests, whether to access feed data or to post new data, and will receive an error* for every request until the rate has diminished. Once the rate has diminished service will return to normal, so you don't have to do anything other than reducing the rate of requests.
Note that this means that you can either make requests regularly, or you can make a burst of requests -- but then you will need to prevent any further requests for another two minutes. Therefore, if you are consistently making requests more frequently than your limit, then none of your requests will ever be successful.
* PLEASE NOTE that in the v1 api this is a 503 error and in the v2 api this a 403 error, as this is more semantically correct.
Non-authenticated access
Non-authenticated access is available for PNG images, summary history and RSS/Atom feeds available to the general public. This enables you, for example, to embed graphs in websites that will be accessed by non-Pachube users. In the future, we will provide finer-grained access control tools for these items, but for the moment they are accessed as detailed in the v1 API.
Data Formats
The Pachube API supports 3 data formats; JSON, XML and CSV. Each of these formats is best suited to a particular purpose. In the v2 API the JSON and XML representations of an environment are interchangeable: i.e. they both represent the same data and metadata.
There are two ways to specify which format you are using:
- Append the format identifier to the URL, e.g. /v2/feeds.json
- Pass the "Accepts" header in the HTTP request, e.g. Accept: application/json
For all of the API, If no format is specified, the JSON format is used. This means that if you don't specify a format we will try and parse all incoming data as JSON, and we will send all outgoing data as JSON. If this is not what you intend, then you must make sure to specify the format explicitly.
If both methods are used to specify the format, the format identifier in the URL takes precedence.
JSON
The JSON data format is particularly suited to web based applications as it can be easily parsed using Javascript in the browser. However it also makes an excellent generic data serialisation format since it has much lower processing overheads than XML and uses less bandwidth to transmit. A full JSON representation looks like the following:
{ "title" : "Pachube Office environment", "description" : "test of manual feed snapshotting", "feed" : "http://api.pachube.com/v2/feeds/504.json", "id" : 504, "status" : "frozen", "website" : "http://www.haque.co.uk/", "updated" : "2010-06-25T11:54:17.463771Z", "version" : "1.0.0", "private" : "false", "creator" : "http://www.pachube.com/users/hdr", "location": { "disposition":"fixed", "ele":"23.0", "name":"office", "lat":51.5235375648154, "exposure":"indoor", "lon":-0.0807666778564453, "domain":"physical" }, "tags" : [ "Tag1", "Tag2" ], "datastreams" : [ { "at" : "2010-06-25T11:54:17.454020Z", "current_value" : "999", "datapoints" : [ { "at" : "2005-06-25T11:54:17.000000Z", "value" : "999" }, { "at" : "2006-06-25T11:54:17.000000Z", "value" : "123" } ], "id" : "3", "max_value" : "999.0", "min_value" : "7.0", "unit": { "type": "conversionBasedUnits", "label": "label", "symbol": "symbol" }, }, { "at" : "2010-06-24T10:05:49.000000Z", "current_value" : "0000017", "datapoints" : [ { "at" : "2010-04-12T11:31:51.133782Z", "value" : "999" } ], "id" : "4", "max_value" : "19.0", "min_value" : "7.0" } ] }
JSON callback: this is used only when requesting JSON formatted responses. Including this parameter will enable the response to be wrapped in the callback method of your choice (particularly useful with Javascript and for creating AJAX applications).
For example, http://api.pachube.com/v2/feeds/504.json?callback=myCallbackFunction will result in a response body of: myCallbackFunction({...}) rather than just {...}. Callbacks may only contain alphanumeric characters and underscores; any invalid characters will be stripped. This conforms to the implementation discussed here: http://developer.yahoo.com/common/json.html#callbackparam.
XML
The Pachube API uses a specific format of XML called EEML (See http://www.eeml.org for more details). It is well suited to integrating with existing systems such as building management systems although it contains the same information as JSON. An example of a full XML representation looks like the following:
<?xml version="1.0" encoding="UTF-8"?> <eeml xmlns="http://www.eeml.org/xsd/0.5.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.5.1" xsi:schemaLocation="http://www.eeml.org/xsd/0.5.1 http://www.eeml.org/xsd/0.5.1/0.5.1.xsd"> <environment updated="2010-06-08T09:30:11Z" id="504" creator="http://www.pachube.com/users/hdr"> <title>Pachube Office environment</title> <feed>http://api.pachube.com/v2/feeds/504.xml</feed> <status>live</status> <website>http://www.haque.co.uk/</website> <private>false</private> <tag>Tag1</tag> <tag>Tag2</tag> <location domain="physical" exposure="indoor" disposition="fixed"> <name>office</name> <lat>51.5235375648154</lat> <lon>-0.0807666778564453</lon> <ele>23.0</ele> </location> <data id="0"> <tag>humidity</tag> <current_value at="2010-06-08T09:30:11.000000Z">311</current_value> <max_value>847.0</max_value> <min_value>0.0</min_value> <unit type="basicSI" symbol="symbol">label</unit> <datapoints> <value at="2009-07-05T09:24:03.339244Z">008</value> <value at="2009-07-05T09:24:03.339244Z">546</value> <value at="2009-07-05T09:24:03.339244Z">123</value> </datapoints> </data> </environment> </eeml>
CSV
CSV is designed for use by very simple embedded devices, such as an Arduino or other low powered microcontroller. It contains none of the metadata that the XML and JSON formats contain (though this can be added separately using the API or the web interface). A full representation of CSV is as follows:
7441,1,2010-06-01T12:01:32.1Z,123 7441,2,2010-06-01T12:01:32.1Z,456 <feed_id>,<datastream_id>,<timestamp>,<value>
Time Zones
Overview
Pachube supports user specified time zones.
There are two places where you can specify the time zone: in your user profile on the website and via a parameter in an API request.
By default the time zone is UTC.
Setting your pachube.com time zone
Once you are logged in to pachube.com you can edit your time zone by following:
my settings -> Profile -> [click here to edit your info + password].
Once you have set your time zone, all times on the website will be displayed in that time zone.
Displaying times in different zones via the API
By default all api GET requests will return timestamps in UTC. In order to override this send timezone as a request parameter.
The timezone parameter can be specified as either a number of hours offset from UTC or as a place name.
For example, to see timestamps in the time zone for Newfoundland:
http://api.pachube.com/v2/feeds?timezone=-3.5
OR:
http://api.pachube.com/v2/feeds?timezone=Newfoundland
The list of supported place names is as follows:
* UTC -11:00 * International Date Line West Midway Island Samoa * UTC -10:00 * Hawaii * UTC -09:00 * Alaska * UTC -08:00 * Pacific Time (US & Canada) Tijuana * UTC -07:00 * Arizona Chihuahua Mazatlan Mountain Time (US & Canada) * UTC -06:00 * Central America Central Time (US & Canada) Guadalajara Mexico City Monterrey Saskatchewan * UTC -05:00 * Bogota Eastern Time (US & Canada) Indiana (East) Lima Quito * UTC -04:30 * Caracas * UTC -04:00 * Atlantic Time (Canada) La Paz Santiago * UTC -03:30 * Newfoundland * UTC -03:00 * Brasilia Buenos Aires Georgetown Greenland * UTC -02:00 * Mid-Atlantic * UTC -01:00 * Azores Cape Verde Is. * UTC +00:00 * Casablanca Dublin Edinburgh Lisbon London Monrovia UTC * UTC +01:00 * Amsterdam Belgrade Berlin Bern Bratislava Brussels Budapest Copenhagen Ljubljana Madrid Paris Prague Rome Sarajevo Skopje Stockholm Vienna Warsaw West Central Africa Zagreb * UTC +02:00 * Athens Bucharest Cairo Harare Helsinki Istanbul Jerusalem Kyev Minsk Pretoria Riga Sofia Tallinn Vilnius * UTC +03:00 * Baghdad Kuwait Moscow Nairobi Riyadh St. Petersburg Volgograd * UTC +03:30 * Tehran * UTC +04:00 * Abu Dhabi Baku Muscat Tbilisi Yerevan * UTC +04:30 * Kabul * UTC +05:00 * Ekaterinburg Islamabad Karachi Tashkent * UTC +05:30 * Chennai Kolkata Mumbai New Delhi Sri Jayawardenepura * UTC +05:45 * Kathmandu * UTC +06:00 * Almaty Astana Dhaka Novosibirsk * UTC +06:30 * Rangoon * UTC +07:00 * Bangkok Hanoi Jakarta Krasnoyarsk * UTC +08:00 * Beijing Chongqing Hong Kong Irkutsk Kuala Lumpur Perth Singapore Taipei Ulaan Bataar Urumqi * UTC +09:00 * Osaka Sapporo Seoul Tokyo Yakutsk * UTC +09:30 * Adelaide Darwin * UTC +10:00 * Brisbane Canberra Guam Hobart Melbourne Port Moresby Sydney Vladivostok * UTC +11:00 * Magadan New Caledonia Solomon Is. * UTC +12:00 * Auckland Fiji Kamchatka Marshall Is. Wellington * UTC +13:00 * Nuku'alofa
Please note that these place names are case-sensitive.
Inserting datapoints using a custom time zone
If you want to use a non-UTC time zone to send your data to Pachube, all you have to do is specify the time offset in the iso8601 formatted time string when sending the data.
For example specifying Rangoon you would enter the date as:
2010-11-10T10:20:30.123456+06:30
How time zone information affects triggers
As stated previously, within the context of a single request to the API, the time zone will either default to UTC, or will take the value of the timezone parameter. What this means in relation to triggers is that if you don't add the timezone parameter when sending an update, then any trigger events caused by the update will be broadcast in UTC, even if the timestamp contained within the update is in some other time zone, or your user profile specifies some other time zone.
This means that if you want to make sure that any triggers you receive are in a specific time zone, then you must alter the script or device sending the updates such that it includes the desired time zone in the request URL when sending in each update. This won't affect the parsing of any time stamps present in the update, all times will still be converted into UTC for storing in our system.