Camera+

← API Home

Web sharing API

This is our basic read-only API. This API was designed to facilitate Twitter client authors to show our users’ content inline in tweet feeds, and our users to integrate their Camera+ photo feed into their blogs or websites. But we're looking forward to seeing what you can do with it!

Basics

Currently this API requires no authentication, registration, or API keys. This may change in the future as traffic increases.

You can help us keep this policy by keeping your code sane. Use caching as much as possible. When using the API in web applications, do not make service requests on each page load - load the information from our service the first time you need it, and then cache it locally on your own servers.

Formats

Any call that returns data can return data as JSON or XML by specifying the required format in the &format= GET parameter. If you don’t specify a format, the default is JSON.

Format GET parameter Configuration
JSON &format=json None
JSONP &format=json &callback=jsonpFunctionName
XML &format=xml None
Plain text &format=plaintext None

A common case will be that you are scanning a feed or text for links to our services, for instance a Twitter client looking for tweeted images, or an IM client looking for quoted photos. The following table lists links that are of interest to API consumers. Any reference that isn't in the table must be treated as a regular web link. They may lead to our product pages, blog posts, or other such content.

Links to our services may appear with the domains campl.us or camerapl.us. You must support both these domains, we are currently in the process of migrating to the latter.

Page type Example URL Regular Expression
Picture pages http://campl.us/hHAP \bhttps?://(?:campl.us|camerapl.us)/[a-zA-Z0-9]+(?!/)\b
User pages http://camerapl.us/user/kalleboo \bhttps?://(?:campl.us|camerapl.us)/user/[a-zA-Z0-9]+(?!/)\b

Picture pages

Each time a user shares one or more photos, a page is created. Unlike most other photo sharing services, there can be more than one photo shared per page.

Picture pages are identified by their short URLs such as http://campl.us/hHAP (or http://camerapl.us/hHAP). The domains also host other, non-picture pages. These can be distinguished easily as they will always contain a forward-slash (/) somewhere in the path, possibly as a trailing character. If you try to make API requests on a non-picture page, you will get an HTTP 404 error.

To get information for page, make an HTTP request to the short url with one of the following extensions:

Thumbnails

Use of these single thumbnails are discouraged, as picture pages often contain more than one image. The recommended method is to use the :urls data call (described below) and show multiple images, or use :count and show a number badge and link to the original page. Read more in our Twitter client recommendations

URL extension Description Example
:120px HTTP redirect to the maximum 120px dimensions scaled version of the first image on the page. Request: GET http://campl.us/hHj2:120px
Response: HTTP 302 redirect, JPEG file.
:480px HTTP redirect to the maximum 480px dimensions scaled version of the first image on the page. Request: GET http://campl.us/hHj2:480px
Response: HTTP 302 redirect, JPEG file.
:800px HTTP redirect to the maximum 800px version of the first image on the page. This is currently the largest size available. Request: GET http://campl.us/hHj2:800px
Response: HTTP 302 redirect, JPEG file.

Metadata

URL extension Description Example
:info Object containing all the information for a page. This contains everything you’d need to recreate one of our HTML pages: Author, tweet text, images, image metadata (EXIF, recipes) and comments Request: GET http://campl.us/hvGw:info

Response: This example has been abbreviated for space.

{
   "page":{
      "timestamp":"2012-01-18 07:06:26",
      "views":59,
      "comments":3,
      "tweet":{
         "id":null,
         "text":"Yoyogi",
         "userid":3336921,
         "username":"kalleboo",
         "realname":"Karl Baron",
         "avatar":"http:\/\/a3.twimg.com\/profile_images\/801976154\/Sk_rmbillede_2010-04-06_kl._17.59.39_normal.jpg"
      },
      "location":{
         "coords":"35.67300941798433 139.7002115474452",
         "name":"Yoyogikamizonocho, Shibuya, Tokyo 151-0052, Japan"
      }
   },
   "pictures":[
      {
         "800px":"http:\/\/pics.campl.us\/f\/2\/2426f43dac4484b985e250fbc8fe1b41.jpg",
         "120px":"http:\/\/pics.campl.us\/t\/2\/2426f43dac4484b985e250fbc8fe1b41.jpg",
         "480px":"http:\/\/pics.campl.us\/iphone\/2\/2426f43dac4484b985e250fbc8fe1b41.jpg",
         "fullwidth":1280,
         "fullheight":960,
         "location":"35.67300941798433 139.7002115474452",
         "recipe":[
            {
               "type":"fx",
               "value":"Vibrant"
            }
         ],
         "exifdata":[
            {
               "title":"Camera",
               "value":"Apple iPhone 4S",
               "style":"main"
            },
            {
               "title":"Exposure",
               "value":"1\/120 sec",
               "style":"main"
            },
            {
               "title":"Aperture",
               "value":"f\/2.4",
               "style":"main"
            }
         ]
      },
      {
         "800px":"http:\/\/pics.campl.us\/f\/d\/d786431f1a9fe67b0e2e5f0a0a5940b2.jpg",
         "120px":"http:\/\/pics.campl.us\/t\/d\/d786431f1a9fe67b0e2e5f0a0a5940b2.jpg",
         "480px":"http:\/\/pics.campl.us\/iphone\/d\/d786431f1a9fe67b0e2e5f0a0a5940b2.jpg",
         "fullwidth":1280,
         "fullheight":960,
         "location":"35.67216666666667 139.7015",
         "recipe":[
            {
               "type":"fx",
               "value":"Vibrant"
            }
         ],
         "exifdata":[
            {
               "title":"Focal Length",
               "value":"4.3 mm",
               "style":""
            },
            {
               "title":"ISO Speed",
               "value":"80",
               "style":""
            },
            {
               "title":"Flash",
               "value":"Off, Did not fire",
               "style":""
            }
         ]
      },
      {
         "800px":"http:\/\/pics.campl.us\/f\/d\/dccdad5c849d16e0c0ce75dc3fac7bfa.jpg",
         "120px":"http:\/\/pics.campl.us\/t\/d\/dccdad5c849d16e0c0ce75dc3fac7bfa.jpg",
         "480px":"http:\/\/pics.campl.us\/iphone\/d\/dccdad5c849d16e0c0ce75dc3fac7bfa.jpg",
         "fullwidth":960,
         "fullheight":1280,
         "location":"35.67525778375641 139.6971892624487",
         "recipe":[
            {
               "type":"scenemode",
               "value":"Auto"
            },
            {
               "type":"fx",
               "value":"Magic Hour (51%)"
            }
         ],
         "exifdata":[
            {
               "title":"Metering Mode",
               "value":"Multi-segment",
               "style":""
            },
            {
               "title":"Light Value",
               "value":"9.4",
               "style":""
            }
         ]
      }
   ],
  "comments": [
    {
      "author": "James Lee Mandy",
      "avatar": "http://profile.ak.fbcdn.net/hprofile-ak-ash2/274084_752769761_5319941_q.jpg",
      "url": "http://www.facebook.com/profile.php?id=752769761",
      "text": "Amazing!!!!"
    },
    {
      "author": "Pixel Psycho ",
      "avatar": "http://a2.twimg.com/profile_images/1315840794/Me_MyBoo_normal.JPG",
      "url": "http://twitter.com/AndyTheJoker",
      "text": "WOW! You rocks guys! Love this app."
    }
  ]
}
URL extension Description Example
:urls List with just the URLs for all sizes of all the images on the page, and the real dimensions of the image Request: GET http://campl.us/hvGw:urls

Response: This example has been abbreviated for space.

[
   {
      "800px":"http:\/\/pics.campl.us\/f\/2\/2426f43dac4484b985e250fbc8fe1b41.jpg",
      "120px":"http:\/\/pics.campl.us\/t\/2\/2426f43dac4484b985e250fbc8fe1b41.jpg",
      "480px":"http:\/\/pics.campl.us\/iphone\/2\/2426f43dac4484b985e250fbc8fe1b41.jpg",
      "fullwidth":1280,
      "fullheight":960
   },
   {
      "800px":"http:\/\/pics.campl.us\/f\/d\/d786431f1a9fe67b0e2e5f0a0a5940b2.jpg",
      "120px":"http:\/\/pics.campl.us\/t\/d\/d786431f1a9fe67b0e2e5f0a0a5940b2.jpg",
      "480px":"http:\/\/pics.campl.us\/iphone\/d\/d786431f1a9fe67b0e2e5f0a0a5940b2.jpg",
      "fullwidth":1280,
      "fullheight":960
   },
   {
      "800px":"http:\/\/pics.campl.us\/f\/d\/dccdad5c849d16e0c0ce75dc3fac7bfa.jpg",
      "120px":"http:\/\/pics.campl.us\/t\/d\/dccdad5c849d16e0c0ce75dc3fac7bfa.jpg",
      "480px":"http:\/\/pics.campl.us\/iphone\/d\/dccdad5c849d16e0c0ce75dc3fac7bfa.jpg",
      "fullwidth":960,
      "fullheight":1280
   }
]
URL extension Description Example
:count The raw number of images on the page (for adding a badge to a thumbnail, or showing e.g. “more…”) Request: GET http://campl.us/hvCY:count

Response:

3

Users

Users are identified by their Twitter usernames. For detailed information on a user, use the appropriate Twitter API.

Users have their own home pages under the /user path, e.g. http://campl.us/user/kalleboo (or http://camerapl.us/user/kalleboo). Requests for users can fail with a 404 if the user has never uploaded anything to campl.us, or 403 if their Twitter timeline is set to private.

User info API

URL extension Description Example
:pages Object with a short user summary, and a list of all their pages and images. Each call returns up to 50 images. Contains a “next” row with the URL to request the next 50 images. Request: GET http://campl.us/user/kalleboo:pages

Response: This example has been abbreviated for space.

{
   "user":{
      "userid":3336921,
      "username":"kalleboo",
      "realname":"Karl Baron",
      "avatar":"http:\/\/a3.twimg.com\/profile_images\/801976154\/Sk_rmbillede_2010-04-06_kl._17.59.39_normal.jpg",
      "pages":322,
      "pictures":398
   },
   "pages":[
      {
         "url":"http:\/\/campl.us\/h7EK",
         "tweettext":"Apple are such a tease. Mailing my Smart Cover almost a week before the iPad :(",
         "tweetid":null,
         "timestamp":"2012-03-12 05:54:13",
         "views":55,
         "comments":0,
         "location":null,
         "locationname":null,
         "images":[
            {
               "800px":"http:\/\/pics.campl.us\/f\/6\/648aae03a9de5af0f05585beedaf8725.jpg",
               "120px":"http:\/\/pics.campl.us\/t\/6\/648aae03a9de5af0f05585beedaf8725.jpg",
               "480px":"http:\/\/pics.campl.us\/iphone\/6\/648aae03a9de5af0f05585beedaf8725.jpg",
               "fullwidth":960,
               "fullheight":720,
               "location":""
            }
         ]
      },
      {
         "url":"http:\/\/campl.us\/h2Wt",
         "tweettext":"Where to run when the local volcano erupts...",
         "tweetid":null,
         "timestamp":"2012-03-05 09:32:31",
         "views":71,
         "comments":0,
         "location":"31.56844473637615 130.5410726672897",
         "locationname":"Korimoto, Kagoshima, Kagoshima Prefecture 890-0065, Japan",
         "images":[
            {
               "800px":"http:\/\/pics.campl.us\/f\/f\/faa181ecbdfb50142d352278e92df6a0.jpg",
               "120px":"http:\/\/pics.campl.us\/t\/f\/faa181ecbdfb50142d352278e92df6a0.jpg",
               "480px":"http:\/\/pics.campl.us\/iphone\/f\/faa181ecbdfb50142d352278e92df6a0.jpg",
               "fullwidth":2571,
               "fullheight":2448,
               "location":"31.56844473637615 130.5410726672897"
            }
         ]
      },
      {
         "url":"http:\/\/campl.us\/hVGg",
         "tweettext":"Fiber to the home FTW",
         "tweetid":null,
         "timestamp":"2012-02-24 07:48:55",
         "views":72,
         "comments":0,
         "location":"31.56839005147831 130.5412602398266",
         "locationname":"Korimoto, Kagoshima, Kagoshima Prefecture 890-0065, Japan",
         "images":[
            {
               "800px":"http:\/\/pics.campl.us\/f\/5\/5af1d0b309192e5ed2c040f9686af052.jpg",
               "120px":"http:\/\/pics.campl.us\/t\/5\/5af1d0b309192e5ed2c040f9686af052.jpg",
               "480px":"http:\/\/pics.campl.us\/iphone\/5\/5af1d0b309192e5ed2c040f9686af052.jpg",
               "fullwidth":2676,
               "fullheight":3492,
               "location":"31.56839005147831 130.5412602398266"
            },
            {
               "800px":"http:\/\/pics.campl.us\/f\/5\/546bded0f17f9d3b0f3db6579de2b936.jpg",
               "120px":"http:\/\/pics.campl.us\/t\/5\/546bded0f17f9d3b0f3db6579de2b936.jpg",
               "480px":"http:\/\/pics.campl.us\/iphone\/5\/546bded0f17f9d3b0f3db6579de2b936.jpg",
               "fullwidth":2676,
               "fullheight":3492,
               "location":"31.56842918979939 130.5410561316298"
            }
         ]
      }
   ],
   "next":"http:\/\/campl.us\/user\/kalleboo:pages?continue=hDx1"
}

User info RSS

Another way to consume user information is by using one of the associated RSS feeds:

URL extension Description Example
/rss The user’s most recent pages http://campl.us/user/kalleboo/rss
/comment_rss Recent comments posted on the user’s pages http://campl.us/user/kalleboo/comment_rss

We also have a basic search API. This will only search public photos. Results are limited to 100 photos (note: photos, not pages). Search results may be up to an hour old.

The search API is beta and subject to change. Please give us feedback on what changes you’d like to see here!

Base URL

http://campl.us/search?

Query variables

Variable Format Description Default
username String Twitter username
tweettext String Tweet text partial match
earliest YYYY-MM-DD HH:MM Return only tweets on or after this date/time (UTC)
latest YYYY-MM-DD HH:MM Return only tweets on or before this date/time (UTC)
locationname String Location name string partial match. Note: location names are missing for pages created before March, 2011.

Example

Request

http://campl.us/search.php?username=kalleboo&locationname=Shibuya

Response: This example has been abbreviated for space.

[
   {
      "url":"http:\/\/campl.us\/hzon",
      "tweettext":"AKB48 taking over the yamanote line",
      "tweetid":null,
      "timestamp":"2012-01-23 07:39:37",
      "views":60,
      "comments":0,
      "location":"35.64686940520596 139.7096049786915",
      "locationname":"Japan, Tokyo, Shibuya, Ebisuminami, \uff11\u4e01\u76ee",
      "user":{
         "userid":"3336921",
         "username":"kalleboo",
         "realname":"Karl Baron",
         "avatar":"http:\/\/a3.twimg.com\/profile_images\/801976154\/Sk_rmbillede_2010-04-06_kl._17.59.39_normal.jpg"
      },
      "images":[
         {
            "800px":"http:\/\/pics.campl.us\/f\/2\/2f49d620c5d147c593623cb513de76cc.jpg",
            "120px":"http:\/\/pics.campl.us\/t\/2\/2f49d620c5d147c593623cb513de76cc.jpg",
            "480px":"http:\/\/pics.campl.us\/iphone\/2\/2f49d620c5d147c593623cb513de76cc.jpg",
            "fullwidth":1074,
            "fullheight":1280,
            "location":"35.64686940520596 139.7096049786915"
         }
      ]
   },
   {
      "url":"http:\/\/campl.us\/hzei",
      "tweettext":"\u30b9\u30bf\u30d0\u3042\u305a\u304d\u62b9\u8336\u30fe(\uff20\u2312\u30fc\u2312\uff20)\u30ce",
      "tweetid":null,
      "timestamp":"2012-01-23 02:01:27",
      "views":51,
      "comments":0,
      "location":"35.65951597880168 139.7008431238492",
      "locationname":"Japan, Tokyo, Shibuya, Dogenzaka, \uff12\u4e01\u76ee",
      "user":{
         "userid":"3336921",
         "username":"kalleboo",
         "realname":"Karl Baron",
         "avatar":"http:\/\/a3.twimg.com\/profile_images\/801976154\/Sk_rmbillede_2010-04-06_kl._17.59.39_normal.jpg"
      },
      "images":[
         {
            "800px":"http:\/\/pics.campl.us\/f\/e\/e1a224dc6ec6f9f0089e205fa2aa0c8b.jpg",
            "120px":"http:\/\/pics.campl.us\/t\/e\/e1a224dc6ec6f9f0089e205fa2aa0c8b.jpg",
            "480px":"http:\/\/pics.campl.us\/iphone\/e\/e1a224dc6ec6f9f0089e205fa2aa0c8b.jpg",
            "fullwidth":1280,
            "fullheight":960,
            "location":"35.65951597880168 139.7008431238492"
         }
      ]
   },
   {
      "url":"http:\/\/campl.us\/hyAz",
      "tweettext":"\u30e9\u30fc\u30e1\u30f3\u30fe(\uff20\u2312\u30fc\u2312\uff20)\u30ce",
      "tweetid":null,
      "timestamp":"2012-01-22 06:48:11",
      "views":72,
      "comments":0,
      "location":"35.65612400000929 139.6952765779779",
      "locationname":"Nanpeidaicho, Shibuya, Tokyo 150-0036, Japan",
      "user":{
         "userid":"3336921",
         "username":"kalleboo",
         "realname":"Karl Baron",
         "avatar":"http:\/\/a3.twimg.com\/profile_images\/801976154\/Sk_rmbillede_2010-04-06_kl._17.59.39_normal.jpg"
      },
      "images":[
         {
            "800px":"http:\/\/pics.campl.us\/f\/4\/47a79fe1dcf50b0efcbba5e11d97d0f3.jpg",
            "120px":"http:\/\/pics.campl.us\/t\/4\/47a79fe1dcf50b0efcbba5e11d97d0f3.jpg",
            "480px":"http:\/\/pics.campl.us\/iphone\/4\/47a79fe1dcf50b0efcbba5e11d97d0f3.jpg",
            "fullwidth":962,
            "fullheight":1280,
            "location":"35.65612400000929 139.6952765779779"
         }
      ]
   }
]

Twitter client UX recommendations

Camera+ presents a slightly unique challenge in that it’s the only service where users regularly share multiple pictures with a single link. When a twitter client sees a picture url, it should read the :urls data, and show a list or grid of all the thumbnails on the page. If space is at a premium, clients can read the :count variable, show only the first thumbnail with a badge in the corner showing the total number of photos, and link to the original page when the user taps the thumbnail.

When displaying more than one image, you can link to anchors on the linked page by using the word “photo” and sequential numbers starting at 1. E.g. link to the third image on a page with http://campl.us/hvaI#photo3

Example: WordPress plugin

This sample WordPress plugin will run hourly in cron and take anything you post on your Twitter stream on campl.us and post it in your blog.

Download

<?php
/*
Plugin Name: campl.us
Plugin URI: http://campl.us
Description: Create posts based on a campl.us profile
Version: 0.1
Author: tap tap tap
Author URI: http://api.camerapl.us/
License: Public domain
*/

if ( ! wp_next_scheduled( 'camplus_cron_hook' ) ) {
  wp_schedule_event( time(), 'hourly', 'camplus_cron_hook' );
}

add_action( 'camplus_cron_hook', 'camplus_check_cron' );

function camplus_check_cron() {
  $wp_author_id = 4;
  $camplus_username = 'kalleboo';
  
  $last_timestamp = get_option('camplus_last_timestamp');
  $new_last_timestamp = $last_timestamp;
  
  echo $last_timestamp;
  
  $data = file_get_contents('http://campl.us/user/'.$camplus_username.':pages');
  $info = json_decode($data,true);
  $x = 0;
  foreach($info['pages'] as $page) {
    if ($page['timestamp'] <= $last_timestamp)
      break;
    
    $text = html_entity_decode($page['tweettext']);
    
    foreach ($page['images'] as $image) {
      $text .= "\n\n";
      $text .= '<img src="'.$image['800px'].'">';
    }
    
    $post = array(
      'post_author' => $wp_author_id, //The user ID number of the author.
      'post_status' => 'publish', //Set the status of the new post. 
      'post_content' => $text, //The full text of the post.
      'post_date_gmt' => $page['timestamp'], //The time post was made, in GMT.
      'post_title' => html_entity_decode($page['tweettext']), //The title of your post.
    );
    
    $post_id = wp_insert_post( $post, $wp_error );     
    add_post_meta($post_id, 'lat_long', str_replace(' ',',',$page['location']), true);
    add_post_meta($post_id, 'city_name', $page['locationname'], true);
    $new_last_timestamp = max($new_last_timestamp,$page['timestamp']);
    
    if (!$last_timestamp) {
      break; //first time we run, just get the latest tweet
    }
  }
  
  if (!$last_timestamp || $new_last_timestamp>$last_timestamp) {
    update_option('camplus_last_timestamp',$new_last_timestamp);
  }
}

if (isset($_GET['force_camplus_update']))
  camplus_check_cron();

?>

Client libraries

These libraries are created and maintained by third parties and we cannot make any guarantees about their performance.

Ruby (kevintuhumury)

A Ruby wrapper around the Camera+ (http://camerapl.us) iPhone app Web Sharing API
Github


tap tap tap