TypePad Atom API

This document describes TypePad's implementation of the Atom API.

This documentation and TypePad's Atom implementation are preliminary and may change until version 1.0 of both the Atom specification and of this document.

Version

This is version 0.03 of this document.

Request and Response Format

TypePad's Atom implementation supports both the REST and SOAP formats of the API.

All methods require authentication. Authentication uses WSSE.

More documentation on these formats, along with the WSSE spec, is linked from http://www.intertwingly.net/wiki/pie/DifferentlyAbledClients. The latest specification of the API itself is at http://bitworking.org/projects/atom/draft-gregorio-09.html.

Root Atom Endpoints

The root endpoints for weblogs, photo albums, and TypeLists are as follows:

  • Weblogs: http://www.typepad.com/t/atom/weblog
  • Photo Albums: http://www.typepad.com/t/atom/gallery
  • TypeLists: http://www.typepad.com/t/atom/lists

All of these endpoints individually implement the Atom API described in the latest specification, with some additional introspection to obtain the user's list of weblogs, photo albums, etc.

Authentication Credentials

Atom authentication uses WSSE, and is represented as an "X-WSSE" HTTP header.

X-WSSE: UsernameToken Username="name", PasswordDigest="digest", Created="timestamp", Nonce="nonce"
Username

The username that the user enters (the TypePad username).

Nonce

A secure token generated anew for each HTTP request.

Created

The ISO-8601 timestamp marking when Nonce was created.

PasswordDigest

A SHA-1 digest of the Nonce, Created timestamp, and the password that the user supplies, base64-encoded. In other words, this should be calculated as:

base64(sha1(Nonce . Created . Password))

Example:

X-WSSE: UsernameToken Username="Melody", PasswordDigest="VfJavTaTy3BhKkeY/WVu9L6cdVA=", Created="2004-01-20T01:09:39Z", Nonce="7c19aeed85b93d35ba42e357f10ca19bf314d622"

URI Types

There are 5 types of URIs that are defined in our Atom implementation.

PostURI

The URI used to post an entry to the weblog.

Corresponds to @rel equal to service.post.

FeedURI

The URI used to obtain a list of all of the posts in the weblog.

Corresponds to @rel equal to service.feed.

EditURI

The URI used to update or obtain a post in the weblog.

Corresponds to @rel equal to service.edit.

UploadURI

The URI used to upload a file (of any MIME type) to a weblog. Note that this is not the same as posting an entry to a weblog; the act of uploading a file merely writes the file to the user's website, but does not create an entry on the weblog.

Corresponds to @rel equal to service.upload.

CategoryURI

The URI used to obtain a list of the categories in the weblog.

Corresponds to @rel equal to service.categories.

Each service-related <link> element in a feed maps to one of the above URIs as associated with one of the user's weblogs. In other words, there will be at least 4 <link> elements for each weblog, each describing a different action.

Typical Usage

1. Listing the User's Weblogs

To get a list of a user's weblogs, make a GET request to the root endpoint with authentication information for the user. The response will consist of a list of <link> tags wrapped in a <feed> element. For each weblog, there will be a number of <link> tags relating to the types of URIs above.

Request:

GET /t/atom/weblog HTTP/1.1
Host: www.typepad.com
X-WSSE: my credentials

Response:

HTTP/1.1 200
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://purl.org/atom/ns#">
  <link rel="service.post" href="http://www.typepad.com/t/atom/weblog/blog_id=1" type="application/x.atom+xml" title="Blog 1" />
  <link rel="service.feed" href="http://www.typepad.com/t/atom/weblog/blog_id=1" type="application/x.atom+xml" title="Blog 1" />
  <link rel="service.post" href="http://www.typepad.com/t/atom/weblog/blog_id=2" type="application/x.atom+xml" title="Blog 2" />
  <link rel="service.feed" href="http://www.typepad.com/t/atom/weblog/blog_id=2" type="application/x.atom+xml" title="Blog 2" />
</feed>

2. Listing the Posts in a Weblog

To obtain a list of the posts in a selected weblog, send a GET request to the FeedURI for the weblog. The response will be formatted as an Atom feed, containing a list of 20 posts. Within the <feed> there will be <link> tags with @rel equal to prev and next if there are more posts available; the URI values for those tags will be the FeedURIs used to obtain those posts.

Request:

GET /t/atom/weblog/blog_id=1 HTTP/1.1
Host: www.typepad.com
X-WSSE: my credentials

Response:

HTTP/1.1 200
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://purl.org/atom/ns#">
  <link rel="alternate" type="text/html" href="http://example.typepad.com/weblog/" />
  <title>Blog 1</title>
  <link rel="service.post" href="http://www.typepad.com/t/atom/weblog/blog_id=1" title="Blog 1" type="application/x.atom+xml" />
  <entry>
    <title>My First Post</title>
    <content mode="xml">Contents of my post</content>
    <issued>2003-10-23T18:35:51Z</issued>
    <link rel="alternate" type="text/html" href="http://example.typepad.com/weblog/2003/10/my_first_post.html" />
    <id>tag:typepad.com,2003:post-3</id>
    <link rel="service.edit" href="http://www.typepad.com/t/atom/weblog/blog_id=1/entry_id=3" title="My First Post" type="application/x.atom+xml" />
  </entry>
</feed>

3. Retrieving a list of categories

To retrieve the list of available categories in a weblog, send a GET request to the CategoryURI.

The response will consist of an http://sixapart.com/atom/category#categories element containing multiple http://purl.org/dc/elements/1.1/subject elements. Each element represents the name of a category in the weblog.

Request:

GET /t/atom/weblog/blog_id=1/svc=categories HTTP/1.1
Host: www.typepad.com
X-WSSE: my credentials

Sample response:

HTTP/1.1 200
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<categories xmlns="http://sixapart.com/atom/category#" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <dc:subject>Books</dc:subject>
  <dc:subject>Travel</dc:subject>
  <dc:subject>Movies</dc:subject>
</categories>

4. Posting an entry

To post an entry to a weblog, send a POST request to the PostURI.

You can specify a category for a weblog post in the optional ement http://purl.org/dc/elements/1.1/subject, which should be the category of the weblog entry. This should be a string taken from the list of available categories obtained by retrieving the list of categories in the weblog.

If the entry is successfully posted, the response will consist of a 201 Created response code.

Request:

POST /t/atom/weblog/blog_id=1 HTTP/1.1
Host: www.typepad.com
X-WSSE: my credentials

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <title>Trip to the Lake</title>
  <dc:subject>Vacation</dc:subject>
  <content type="application/xhtml+xml" mode="xml"><div xmlns="http://www.w3.org/1999/xhtml"><img src="http://example.typepad.com/photos/vacation/lake-thumb.jpg" /> Here is a picture of me at the lake.</div></content>
</entry>

Response:

HTTP/1.1 200
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#">
  <title>Trip to the Lake</title>
  <content mode="xml"><div xmlns="http://www.w3.org/1999/xhtml"><img src="http://example.typepad.com/photos/vacation/lake-thumb.jpg" /> Here is a picture of me at the lake.</div></content>
  <issued>2003-10-23T18:35:51Z</issued>
  <link rel="alternate" href="http://example.typepad.com/weblog/2003/10/trip_to_the_lake.html" type="text/html" />
  <id>tag:typepad-com:post:3</id>
  <link rel="service.edit" href="http://www.typepad.com/t/atom/weblog/blog_id=1/entry_id=3" title="Trip to the Lake" type="application/x.atom+xml" />
</entry>

5. Retrieving a Post

Each entry in the feed has an EditURI. A GET request to this URI will return the full entry in Atom format for editing; a PUT request to this URI will update the entry, and a successful response to updating a post will be marked with a 200 OK header.

Request to retrieve entry:

GET /t/atom/weblog/blog_id=1/entry_id=3 HTTP/1.1
Host: www.typepad.com
X-WSSE: my credentials

Response:

HTTP/1.1 200
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#">
  <title>My First Post</title>
  <content mode="xml">Contents of my post</content>
  <issued>2003-10-23T18:35:51Z</issued>
  <link rel="alternate" type="text/html" href="http://example.typepad.com/weblog/2003/10/my_first_post.html" />
  <id>tag:typepad.com,2003:post-3</id>
  <link rel="service.edit" href="http://www.typepad.com/t/atom/weblog/blog_id=1/entry_id=3" title="My First Post" type="application/x.atom+xml" />
</entry>

6. Deleting a Post

A DELETE request to the EditURI for a post will delete the post. A successful response will be marked with a 200 OK header.

Request to retrieve entry:

DELETE /t/atom/weblog/blog_id=1/entry_id=3 HTTP/1.1
Host: www.typepad.com
X-WSSE: my credentials

Response:

HTTP/1.1 200
Content-Type: application/x.atom+xml

Atom Entry Elements

Photo Albums

For TypePad's Photo Album API, we use the standard Atom namespace for certain elements and a custom namespace, http://sixapart.com/atom/photo#, for additional metadata.

The following entry elements are used in creating new photos and editing existing photos.

http://purl.org/atom/ns#title

The name of the photo. Required.

http://purl.org/atom/ns#summary

A caption for the photo. Optional.

http://sixapart.com/atom/photo#filename

The filename of the photo, including a file extension. Optional.

If not provided, the filename will be set automatically based on the title and the content type. (See content, below.)

http://sixapart.com/atom/photo#location

The location where the photo was taken. Optional.

http://sixapart.com/atom/photo#taken

The date and time at which the photo was taken, in ISO-8601 format.

http://purl.org/atom/ns#issued

The date and time at which the photo was uploaded to TypePad, in ISO-8601 format.

http://purl.org/atom/ns#content

The binary photo data, base-64 encoded and marked as such in the standard content element. Required. If filename is not provided, the content element MUST have a @type attribute for the content type.

TypeLists

For the TypeList API, we use the standard Atom namespace for certain elements, and custom namespaces for additional metadata.

In designing the namespaces for TypeLists, we have tried to leverage existing specifications such as RVW and bio, as well as using as much of the Atom format as possible. This has been balanced with a desire to encapsulate as much information as possible about the item itself (a book, for example) in its own namespace.

Because different TypeLists have different requirements for the metadata they contain, each type uses a different set of elements.

  • Music
    http://sixapart.com/atom/song#title

    The song title.

    http://sixapart.com/atom/song#album

    The album title.

    http://sixapart.com/atom/song#artist

    The artist name.

    http://sixapart.com/atom/song#thumbnail

    The URL of the image thumbnail of the album cover.

    http://purl.org/NET/RVW/0.1/value

    The numeric rating given to the track (must be in the range 1 – 5).

    http://purl.org/atom/ns#content

    Textual notes and/or review of the track.

    http://purl.org/atom/ns#title

    The title of the item, in "Artist Name - Song Title" format. Read-only; IGNORED in PostURI and EditURI.

    http://purl.org/atom/ns#issued

    The date and time at which the item was added to TypePad.

  • Books
    http://sixapart.com/atom/book#isbn

    The ISBN of the book. If this is provided, title and author will be automatically looked up on Amazon.com.

    http://sixapart.com/atom/book#title

    The book title.

    http://sixapart.com/atom/book#author

    The book author.

    http://sixapart.com/atom/book#thumbnail

    The URL of the image thumbnail of the book cover.

    http://purl.org/NET/RVW/0.1/value

    The numeric rating given to the book (must be in the range 1 – 5).

    http://purl.org/atom/ns#content

    Textual notes and/or review of the book.

    http://purl.org/atom/ns#title

    The title of the item, in "Author Name: Book Title" format. Read-only; IGNORED in PostURI and EditURI.

    http://purl.org/atom/ns#issued

    The date and time at which the item was added to TypePad.

  • People
    http://sixapart.com/atom/person#homepage

    The website URL of the person. If this is provided, TypePad will attempt to fill in the rest of the information automatically from an auto-discovered FOAF file.

    http://sixapart.com/atom/person#name

    The person's name.

    http://sixapart.com/atom/person#homepage_name

    The person's weblog or website name.

    http://sixapart.com/atom/person#email

    The email address of the person.

    http://sixapart.com/atom/person#foaf_url

    The URL of the person's FOAF file.

    http://purl.org/vocab/bio/0.1/olb

    Short (one-line) biography of the person and/or notes.

    http://purl.org/atom/ns#title

    The person's name. Read-only; IGNORED in PostURI and EditURI.

    http://purl.org/atom/ns#issued

    The date and time at which the item was added to TypePad.

  • Links
    http://sixapart.com/atom/link#url

    The site URL. If this is provided, TypePad will attempt to fill in the site title automatically by looking at its title tag.

    http://sixapart.com/atom/link#title

    The site title.

    http://purl.org/atom/ns#content

    Notes and/or review of the site.

    http://purl.org/atom/ns#title

    The site title. Read-only; IGNORED in PostURI and EditURI.

    http://purl.org/atom/ns#issued

    The date and time at which the item was added to TypePad.

Examples

Adding a Book Using an ISBN

Sending this request to the PostURI for a Reading TypeList will create a new item using the given ISBN, along with a rating and a review. The author, title, and thumbnail URL will be automatically pulled from Amazon.com.

Request:

POST /t/atom/lists/list_id=1 HTTP/1.1
Host: www.typepad.com
X-WSSE: my credentials

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#" xmlns:book="http://sixapart.com/atom/book#" xmlns:rvw="http://purl.org/NET/RVW/0.1/">
  <book:isbn>0375412808</book:isbn>
  <content>This is a funny book.</content>
  <rvw:value>4</rvw:value>
</entry>

Response:

HTTP/1.1 201 Created
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#" xmlns:book="http://sixapart.com/atom/book#" xmlns:rvw="http://purl.org/NET/RVW/0.1/">
  <title>Jeffrey Steingarten: It Must've Been Something I Ate: The Return of the Man Who Ate Everything</title>
  <issued>2003-12-05T00:21:54Z</issued>
  <id>tag:typepad.com,2003:listitem-201</id>
  <book:title>It Must've Been Something I Ate: The Return of the Man Who Ate Everything</book:title>
  <book:author>Jeffrey Steingarten</book:author>
  <content>This is a funny book.</content>
  <rvw:value>4</rvw:value>
  <book:isbn>0375412808</book:isbn>
  <book:thumbnail>http://images.amazon.com/images/P/0375412808.01.THUMBZZZ.jpg</book:thumbnail>
</entry>

This example using the XML::Atom Perl module:

use XML::Atom::Entry;
use XML::Atom::Client;
use XML::Atom;

my $PostURI = 'http://www.typepad.com/t/atom/lists/list_id=1';

my $api = XML::Atom::Client->new;
$api->username('Melody');
$api->password('Nelson');

my $book = XML::Atom::Namespace->new(book => 'http://sixapart.com/atom/book#');
my $rvw = XML::Atom::Namespace->new(rvw => 'http://purl.org/NET/RVW/0.1/');

my $entry = XML::Atom::Entry->new;
$entry->set($book, 'isbn', '0375412808');
$entry->content('This is a funny book.');
$entry->set($rvw, 'value', 4);

my $EditURI = $api->createEntry($PostURI, $entry)
    or die $api->errstr;

Adding a Song to a Music TypeList

Sending this request to the PostURI for a Music TypeList will create a new item using the given artist, album, and song title, along with a rating and a review. The thumbnail URL will be automatically pulled from Amazon.com.

Request:

POST /t/atom/lists/list_id=1 HTTP/1.1
Host: www.typepad.com
X-WSSE: my credentials

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#" xmlns:song="http://sixapart.com/atom/song#" xmlns:rvw="http://purl.org/NET/RVW/0.1/">
  <song:title>Lucky Star</song:title>
  <song:album>Kish Kash</song:album>
  <song:artist>Basement Jaxx</song:artist>
  <content>Good song.</content>
  <rvw:value>4</rvw:value>
</entry>

Response:

HTTP/1.1 201 Created
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#" xmlns:book="http://sixapart.com/atom/book#" xmlns:rvw="http://purl.org/NET/RVW/0.1/">
  <title>Basement Jaxx - Lucky Star</title>
  <issued>2003-12-05T10:23:38Z</issued>
  <id>tag:typepad.com,2003:listitem-153281</id>
  <song:title>Lucky Star</song:title>
  <song:album>Kish Kash</song:album>
  <song:artist>Basement Jaxx</song:artist>
  <content>Good song.</content>
  <rvw:value>4</rvw:value>
  <song:thumbnail>http://images.amazon.com/images/P/B0000DD56E.01.THUMBZZZ.jpg</song:thumbnail>
</entry>

This example using the XML::Atom Perl module:

use XML::Atom::Entry;
use XML::Atom::Client;
use XML::Atom;

my $PostURI = 'http://www.typepad.com/t/atom/lists/list_id=1';

my $api = XML::Atom::Client->new;
$api->username('Melody');
$api->password('Nelson');

my $song = XML::Atom::Namespace->new(song => 'http://sixapart.com/atom/song#');
my $rvw = XML::Atom::Namespace->new(rvw => 'http://purl.org/NET/RVW/0.1/');

my $entry = XML::Atom::Entry->new;
$entry->set($song, 'title', 'Lucky Star');
$entry->set($song, 'album', 'Kish Kash');
$entry->set($song, 'artist', 'Basement Jaxx');
$entry->content('This is a funny book.');
$entry->set($rvw, 'value', 4);

my $EditURI = $api->createEntry($PostURI, $entry)
    or die $api->errstr;

Adding a Photo to a Photo Album

Sending this request to the PostURI for a TypePad Photo Album will create a new photo. Any EXIF and IPTC metadata will be automatically pulled out of the photo data. Photo content should always be sent in base64 mode.

As a bandwidth consideration, the server will not return the original content posted in the response.

Request:

POST /t/atom/gallery/set_id=1 HTTP/1.1
Host: www.typepad.com
X-WSSE: my credentials

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#" xmlns:photo="http://sixapart.com/atom/photo#">
  <title>At the Lake</title>
  <summary>This is my favorite photo from our trip.</summary>
  <content mode="base64" type="image/jpeg">/9j/2wCEAAQDAwQDAw.../9n/AA==</content>
</entry>

Response:

HTTP/1.1 201 Created
Content-Type: application/x.atom+xml

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://purl.org/atom/ns#" xmlns:photo="http://sixapart.com/atom/photo#">
  <title>At the Lake</title>
  <summary>This is my favorite photo from our trip.</summary>
  <issued>2003-12-05T10:51:15Z</issued>
  <photo:location />
  <photo:thumbnail>http://example.typepad.com/photos/vacation/at_the_lake-thumb.jpg</photo:thumbnail>
  <photo:taken>2003-12-05T10:51:14Z</photo:taken>
  <link rel="alternate" type="text/html" href="http://example.typepad.com/photos/vacation/at_the_lake.html" />
  <id>tag:typepad.com,2003:photo-151233</id>
</entry>

This example using the XML::Atom Perl module:

use XML::Atom::Entry;
use XML::Atom::Client;
use XML::Atom;
use File::Basename;

my $PostURI = 'http://www.typepad.com/t/atom/gallery/set_id=9792';

my $name = shift or die "usage: $0 <photo>";
open my $fh, $name or die $!;
binmode $fh;
my $data = do { local $/; <$fh> };
close $fh;

my $api = XML::Atom::Client->new;
$api->username('Melody');
$api->password('Nelson');

my $entry = XML::Atom::Entry->new;
$entry->content($data);
$entry->content->type('image/jpeg');
$entry->title('At the Lake');
$entry->summary('This is my favorite photo from our trip.');

my $EditURI = $api->createEntry($PostURI, $entry)
    or die $api->errstr;

Changelog

0.3

  • Added sections on retrieving categories, posting entries, and deleting entries to "Typical Usage".
  • Added description of different URIs returned by TypePad.
  • Added description of WSSE.

0.02

  • http://sixapart.com/atom/photo#filename is no longer required on requests to the PostURI for a photo album, and will be determined automatically from the title and content type.
  • Changed instances of the old version of the <link> tag to the new version with attributes.
  • Updated tag: URN format for <id> elements.

0.01

Initial version.