Full Developer API

The Instapaper API allows third-party applications to add URLs to Instapaper. If you only need to add URLs from your application to an Instapaper customer’s account, consider using the Simple API.

Use of the API constitues agreement to the API Terms of Use. Please read it, really. It’s short and contains important implementation rules.

Beta

The Full API is currently in beta. Implementations, details, rules, and available methods may change rapidly and without notice during the beta period.

If you find a bug, or a minor change in the API could make your life a lot easier, please send feedback.

Overview

This API has been designed for ease of implementation. All methods and requirements are intentionally kept very simple, with one exception: almost all functionality requires OAuth.

OAuth

I know OAuth can be daunting, but there are a lot of helper libraries available. I believe the benefits to both Instapaper and its users are worth the OAuth hurdle.

Instapaper’s OAuth implementation is different from what you may be accustomed to: there is no request-token/authorize workflow. This makes it much simpler. Instead, Instapaper uses an implementation of xAuth very similar to Twitter’s. So you still need to sign your requests, but getting tokens is simple.

xAuth is the only way to get an Instapaper access token.

Other details:

Get a token for your application

To get an OAuth consumer token for your application, fill this out.

All token requests are reviewed by a human before being activated.

Subscription accounts

Most of the Full API’s methods require the authenticating user to have a Subscription account.

Only these methods may be used for users without a Subscription:

Effectively, any application that only needs to add pages to someone’s Instapaper account, like a Twitter client or RSS reader, can function completely with these methods, and therefore does not require its users to have Instapaper Subscriptions.

Note: If you only need these methods and prefer a simpler implementation without OAuth, consider using the Simple API.

Users with Subscriptions are required for the deeper functionality that full Instapaper clients and other complex applications require.

Instapaper is self-funded and pays nearly all of its expenses with revenue from the Instapaper iPhone app and the ads on the website, but customers using these advanced API methods may never buy the iPhone app or visit the website. Subscriptions cover the cost of hosting these API methods.

Output formats

Instapaper strings are always encoded in UTF-8, and Instapaper expects all input to be in UTF-8.

Unless otherwise noted, output from every method is an array. The output array is returned as JSON by default.

Each item in the array is an associative array (a hash) containing simple named parameters, each with a type key to describe it. Possible type values:

Example output:

[{"type":"user", "user_id":543210, "username":"TestUserOMGLOL"},
 {"type":"bookmark", "bookmark_id":1234, "url":"http:\/\/www.example.com\/page1.html", "title":"Example page 1", "description":"An example page."},
 {"type":"bookmark", "bookmark_id":1235, "url":"http:\/\/www.example.com\/page2.html", "title":"Example page 2", "description":"Another example page."},
 {"type":"bookmark", "bookmark_id":1236, "url":"http:\/\/www.example.com\/page3.html", "title":"Example page 3", "description":"Yet another example page."}]

Errors are returned in the same way whenever possible, e.g.:

[{"type":"error", "error_code":1240, "message":"Invalid URL specified"}]

The message value in errors is meant to assist programmers during development and debugging, and is not intended to be displayed to users.

If the response is not valid JSON, it should be interpreted as an HTTP 503 “Service Temporarily Unavailable” error, and the request should be retried later.

The qline format

A simple custom format called qline is also supported for environments without convenient JSON decoding, but with a URL-decode string function. (If anyone ever asks, the way to pronounce it is “Queue-Line”, because it’s short for Query-String Line.)

Every method accepts the optional parameter format=qline to get qline output.

This format encodes Instapaper’s array items as lines, separated by a standard \n newline character, with each line being encoded like a URL query-string. For example:

type=user&user_id=543210&username=TestUserOMGLOL
type=bookmark&bookmark_id=1234&url=http%3A%2F%2Fwww.example.com%2Fpage1.html&title=Example%20page%201&description=An%20example%20page.
type=bookmark&bookmark_id=1235&url=http%3A%2F%2Fwww.example.com%2Fpage2.html&title=Example%20page%202&description=Another%20example%20page.
type=bookmark&bookmark_id=1236&url=http%3A%2F%2Fwww.example.com%2Fpage3.html&title=Example%20page%203&description=Yet%20another%20example%20page.

Errors work the same way:

type=error&error_code=1240&message=Invalid%20URL%20specified

These can be quickly decoded with this pseudocode algorithm:

objects = {}
for each line in input.split("\n"):
    attributes = {}
    for each pair in line.split("&"):
        parts = pair.split("=");
        attributes[parts[0]] = url_decode(parts[1]);

    if (attributes[type] is set) objects.append(attributes)

return objects

Empty lines should be ignored. If the response is not parseable, or has no recognizable objects with known type values, it should be interpreted as an HTTP 503 “Service Temporarily Unavailable” error, and the request should be retried later.

Account methods

/api/1/oauth/access_token

Gets an OAuth access token for a user. HTTPS is required: https://www.instapaper.com/api/1/oauth/access_token

Input parameters:

Output on success: A single-line qline-like output (not JSON, to match conventions when issuing access tokens) with the OAuth access token and secret to use, e.g.:

oauth_token=aabbccdd&oauth_token_secret=efgh1234

Generated tokens and secrets are currently each up to 50 characters long. They are case-sensitive and may contain letters and numbers, but will not contain other symbols.

/api/1/account/verify_credentials

Returns the currently logged in user.

Output on success: A user object, e.g.

[{"type":"user","user_id":54321,"username":"TestUserOMGLOL"}]

Bookmark methods

/api/1/bookmarks/list

Lists the user’s unread bookmarks, and can also synchronize reading positions.

Input parameters:

Output: One meta object, the current user, and between 0 and limit bookmarks.

The “have” parameter:

This is a comma-separated list of bookmark_id values that the client already has in its local bookmark data, and shouldn’t be re-sent. Any IDs sent in the have parameter that would not have appeared in the list within the given limit are returned in a delete_ids parameter on the meta object.

The have parameter can just be a list of the bookmark_id values, e.g.:

12345,12346,12347

…in which case Instapaper won’t include those bookmarks in the output.

But it can also do more. Each bookmark returned by the API has a hash value, which is computed from its URL, title, description, and reading progress. If you join the hash value you have for an article with its article ID using a colon, e.g.:

12345:OjMuzFp6,12346:0n4ONgYs,12347:YXo82wTR

…then Instapaper will omit those bookmarks from the output, but only if the hashes haven’t changed. So you can use this method to selectively be informed of updates to article metadata without otherwise re-downloading the entire list on each update.

Finally, you can optionally append two more fields to each ID with colons to indicate how far the user has read each article, as a floating-point value between 0.0 and 1.0 to indicate progress and the Unix timestamp value of the time that the progress was recorded, e.g.:

12345:OjMuzFp6:0.5:1288584076

This would indicate that the bookmark with bookmark_id=12345 and hash=OjMuzFp6 was read to 0.5 progress, or 50% of its length, at timestamp 1288584076 (2010-11-01 12:01:16am EST). If the server’s information is less recent than this, it will update the bookmark and return it in the output with a new hash value.

/api/1/bookmarks/update_read_progress

Updates the user’s reading progress on a single article. This functionality is included in the have parameter of the /api/1/bookmarks/list operation above, but this method exists in case you want to call it separately.

Input parameters:

Output: The modified bookmark on success.

/api/1/bookmarks/add

Adds a new unread bookmark to the user’s account.

Input parameters:

Output: The bookmark on success, which may not be new: if this user already saved this URL, it will be moved to the top of the Unread list (or the specified folder) and assigned the new values for title, description, and content (see below).

In addition to standard invalid-parameter errors, you may encounter these special errors:

Supplying HTML content for a bookmark

You can optionally supply the full HTML content of pages that Instapaper wouldn’t otherwise be able to crawl from its servers, such as pages that require logins or subscriptions.

A bookmark’s content is not shared to other users through any sharing functionality (such as Starred-folder subscriptions). It is only used to generate the text version of the bookmark for the user that created it.

This is not for material that doesn’t have a dedicated, permanent URL or should be excluded from sharing and tracking functionality completely, such as a private message on a social network, driving directions, or the results of a session. For that, see “Private sources” below.

Private sources

Bookmarks can be private, such as the bookmarks that result from Instapaper’s email-in text feature. Private bookmarks are not shared to other users through any sharing functionality (such as Starred-folder subscriptions), and they do not have URLs.

Set this parameter to a non-empty string to set a bookmark to private:

When using this, values passed to url will be ignored, and the content parameter (above) is required.

In any bookmark objects output by this API, the private_source field will be an empty string for public bookmarks, and this value for private bookmarks. They will have an automatically generated, non-functioning value in the url field of the form instapaper://private-content/.... Do not use these URLs in your application.

/api/1/bookmarks/delete

Permanently deletes the specified bookmark. This is NOT the same as Archive. Please be clear to users if you’re going to do this.

Input parameter: bookmark_id

Output: An empty array on success.

/api/1/bookmarks/star

Stars the specified bookmark.

Input parameter: bookmark_id

Output: The modified bookmark on success.

/api/1/bookmarks/unstar

Un-stars the specified bookmark.

Input parameter: bookmark_id

Output: The modified bookmark on success.

/api/1/bookmarks/archive

Moves the specified bookmark to the Archive.

Input parameter: bookmark_id

Output: The modified bookmark on success.

/api/1/bookmarks/unarchive

Moves the specified bookmark to the top of the Unread folder.

Input parameter: bookmark_id

Output: The modified bookmark on success.

/api/1/bookmarks/move

Moves the specified bookmark to a user-created folder.

Input parameters: bookmark_id, folder_id

Output: The modified bookmark on success.

/api/1/bookmarks/get_text

Returns the specified bookmark’s processed text-view HTML, which is always text/html encoded as UTF-8.

Input parameters: bookmark_id

Output: HTML with an HTTP 200 OK status, not the standard API output structures, or an HTTP 400 status code and a standard error structure if anything goes wrong.

Folder methods

/api/1/folders/list

Input parameters: None.

Output: A list of the account’s user-created folders. This only includes organizational folders and does not include RSS-feed folders or starred-subscription folders, as the implementation of those is changing in the near future.

/api/1/folders/add

Creates an organizational folder.

Input parameters: title

Output: The newly created folder, or error 1250: “User already has a folder with this title” if the title isn’t unique among this user’s folders.

/api/1/folders/delete

Deletes the folder and moves any articles in it to the Archive.

Input parameter: folder_id

Output: An empty array on success.

/api/1/folders/set_order

Re-orders a user’s folders.

Input parameter: order, a set of folder_id:position pairs joined by commas, where the position is a positive integer 32 bits or less. Example input, given the folder_ids 100, 200, and 300, wanting to order them in that order:

100:1,200:2,300:3

Or, to reverse their order:

100:3,200:2,300:1

The order of the pairs doesn’t matter, only the position values do, so this is equivalent to the above value:

300:1,100:3,200:2

You must include all of the user’s folders for consistent ordering. Invalid or missing folder IDs or positions will be ignored and will not return errors.

Output: The user’s re-ordered folder list.

Errors

These are the most common errors you may receive.

General errors:

Bookmark errors:

Folder errors:

Operational errors:

About Instapaper credentials

Every user has a unique username (doesn’t have to be an email address, but often is). Passwords are not required, and most users do not have a password. Any interface prompting the user for credentials must accommodate this — for example, you cannot assume that an empty password is a user error.

Authentication behavior:

Preferred language

Wherever possible, please conform to the interface standards of your environment.

When prompting for the username, please label the field “Email or username”, “Email address or username”, or “Username”. Do not label it only “Email”, since many usernames are not email addresses.

If possible, when prompting for an Instapaper password, clarify that it is only required if they actually have a password. For example, on the website’s login form, the box is labeled “Password, if you have one.”

Suggested button or menu titles for the save-URL action: “Send to Instapaper”, “Instapaper: Read Later”, “Read Later with Instapaper”, “Read Later”. Please avoid adding “you” or “me”, e.g. “your Instapaper account”, “my Instapaper”, etc. in this context. (But that’s fine when prompting for credentials.)