{"body": {"type": "/type/text", "value": "## Read API\r\n\r\n<script src=\"/static/js/json2.js\" type=\"text/javascript\"></script>\r\n\r\n<script>\r\nfunction query(request, response) {\r\n    \r\n    request = JSON.stringify(request, null, \"    \").replace(/\\//g, '\\\\/'); \r\n    response = JSON.stringify(response, null, \"    \").replace(/\\//g, '\\\\/'); // simplejson escapes /. DO samething here.\r\n    \r\n    var a = $(\"<div>\").append($(\"<pre>\").append(request)).addClass(\"query\").css(\"width\", \"400px\");\r\n    var b = $(\"<div>\").append($(\"<pre>\").append(response)).addClass(\"response\").css(\"width\", \"400px\");\r\n        \r\n    var tr = $(\"<tr>\")\r\n        .append($(\"<td>\").append(a).attr(\"valign\", \"top\"))\r\n        .append($(\"<td>\").append(\"&#x21D2;\").attr(\"valign\", \"top\").addClass(\"arrow\"))\r\n        .append($(\"<td>\").append(b).attr(\"valign\", \"top\"));\r\n    \r\n    var table = $(\"<table>\").append(tr)\r\n        .attr(\"cellpadding\", 0)\r\n        .attr(\"cellspacing\", 0)\r\n        .attr(\"border\", 0)\r\n        .css(\"width\", \"800px\");\r\n        \r\n    var div = $(\"<div>\").append(table).css(\"margin-left\", \"100px\");\r\n    document.write(div.parent().html());\r\n}\r\n</script>\r\n\r\nInfogami provides an API to query the database for objects matching particular criteria or to `get` an object from the database. All the requests take input either as part of the URL or query string. You can try sample requests and practice building requests in the <a href=\"/api_sandbox\">API sandbox</a>.\r\n\r\n\r\n<ul style=\"padding-left: 224px;\">\r\n  <li><a href=\"#querying\">Querying for Objects (/things)</a></li>\r\n  <li><a href=\"#getting\">Getting an Object (/get)</a></li>\r\n  <li><a href=\"#versions\">Queries for Versions (/versions)</a></li>\r\n  <li><a href=\"#search\">Search queries (/search)</a></li>\r\n</ul>\r\n\r\n\r\nThe database structure, developed by the Open Library, is called <em>infogami</em>. Infogami stores a collection of objects, called \"things\". For example, on the Open Library site, each page, book, author, and user is a thing in the database. Each thing then has a series of arbitrary key-value pairs as properties. For example, a book thing may have the key \"title\" with the value \"A Heartbreaking Work of Staggering Genius\" and the key \"genre\" with the value \"Memoir\". Each collection of key-value pairs is stored as a version, along with the time it was saved and the person who saved it. \r\n\r\nBecause in infogami everything is an object, you can query for any object in infogami space, such as templates, editions, authors, or individual infogami fields in any page type. Each object has an object type. (<a href=\"/type\">List of types.</a>) For example, there is `/type/edition` which represents all of the information about a book, and `type/edition/isbn_10` which is the property for the 10-character ISBN in the edition record.\r\n  \r\n<br clear=\"all\" />\r\n<a name=\"querying\">&nbsp;</a>\r\n\r\n### Querying for Objects (/things)\r\nTo find objects matching a particular query, send a GET request to <http://openlibrary.org/api/things> with `query` as parameter. In this documentation we use curl as a simple command line query client; any software that supports http `GET` can be used.  \r\n\r\nThe `query` must use <a href=\"http://www.ietf.org/rfc/rfc4627.txt?number=4627\">JSON</a> dictionary syntax.\r\n\r\nThis query searches for all editions with a particular ISBN value, and returns the keys of all matching records. Since there can be only one book with the any ISBN, the result contains only one key. (In practice unfortunately you will see publishers have reused an ISBN for otherwise unrelated works.)\r\n\r\n<div class=\"query\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre>\r\nvar request = {\r\n    \"type\": \"/type/edition\",\r\n    \"isbn_10\": \"0789312239\",\r\n};\r\nvar response = {\r\n    \"status\": \"ok\", \r\n    \"result\": [\r\n       \"\\/b\\/OL3315616M\"\r\n    ]\r\n};\r\nquery(request, response);\r\n</pre></div>\r\n\r\nA curl request for the above, then, would read as follows:\r\n\r\n<div class=\"query\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre>\r\n$ curl -G --data-urlencode 'query={\"type\":\"\\/type\\/edition\", \"isbn_10\":\"0789312239\"}' \\\r\nhttp://openlibrary.org/api/things</pre>\r\n</div>\r\n\r\n#### Pattern matching\r\n\r\nThe API supports querying for objects based of string matching. \r\n\r\nHere is an example to get all object with key starting from `/about/`.\r\n\r\n<div class=\"query\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre>\r\nvar request = {\r\n    \"key~\": \"/about/*\"\r\n};\r\n\r\nvar response = {\r\n    \"status\": \"ok\", \r\n    \"result\": [\r\n        \"\\/about\\/architecture\", \r\n        \"\\/about\\/banned\", \r\n        \"\\/about\\/calendar\", \r\n        \"\\/about\\/catalog\", \r\n        \"\\/about\\/contact\", \r\n        \"\\/about\\/faq\", \r\n        \"\\/about\\/help\", \r\n        \"\\/about\\/help\\/libraries\", \r\n        \"\\/about\\/help\\/oclc\", \r\n        \"\\/about\\/help\\/upload\", \r\n        \"\\/about\\/infogami-dc\", \r\n        \"\\/about\\/jobs\", \r\n        \"\\/about\\/lib\", \r\n        \"\\/about\\/ol_info_sheet\", \r\n        \"\\/about\\/olmeeting2008\", \r\n        \"\\/about\\/oln\", \r\n        \"\\/about\\/pagelist\", \r\n        \"\\/about\\/people\", \r\n        \"\\/about\\/performance\", \r\n        \"\\/about\\/press\", \r\n        \"\\/about\\/publishers\", \r\n        \"\\/about\\/relnote\", \r\n        \"\\/about\\/sample_publisher_letter\", \r\n        \"\\/about\\/schema\", \r\n        \"\\/about\\/tech\", \r\n        \"\\/about\\/vision\"\r\n    ]\r\n};\r\n\r\nquery(request, response);\r\n</pre></div>\r\n\r\nDue to performance reasons, `*` is allowed only at the end of a string.\r\n\r\n#### The Sort Directive\r\n\r\nThe `sort` directive can be used to tell Infogami to sort the results of a query before returning. \r\n\r\nThe following query gives the list of all documents sorted in the order of their keys.\r\n\r\n<div class=\"query\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre>\r\nvar request = {\r\n    \"type\": \"/type/doc\",\r\n    \"sort\": \"key\"\r\n};\r\nvar response = {\r\n    \"status\": \"ok\", \r\n    \"result\": [\r\n        \"\\/dev\\/docs\\/api\", \r\n        \"\\/dev\\/docs\\/infogami\", \r\n        \"\\/dev\\/docs\\/ui\"\r\n    ]\r\n};\r\nquery(request, response);\r\n\r\n</pre></div>\r\n\r\nBy default sort operation returns the results in the ascending order. To reverse that order, prepend minus (`-`) to the value of `sort` directive.\r\n\r\n<div class=\"query\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre>\r\nvar request = {\r\n    \"type\": \"/type/doc\",\r\n    \"sort\": \"-key\"\r\n};\r\nvar response = {\r\n    \"status\": \"ok\", \r\n    \"result\": [\r\n        \"\\/dev\\/docs\\/ui\", \r\n        \"\\/dev\\/docs\\/infogami\", \r\n        \"\\/dev\\/docs\\/api\"\r\n    ]\r\n};\r\n\r\nquery(request, response);\r\n\r\n</pre></div>\r\n\r\n#### Limiting Queries\r\n\r\nBy default every results of every query are limited to 100 values. Alternate limit can be specified by using the `limit` directive.\r\n\r\nHere is an example to get first 10 templates. \r\n\r\n<div class=\"query\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre>\r\nvar request = {\r\n    \"type\": \"/type/template\",\r\n    \"sort\": \"key\",\r\n    \"limit\": 10\r\n};\r\nvar response = {\r\n    \"status\": \"ok\", \r\n    \"result\": [\r\n        \"/templates/advanced_search.tmpl\", \r\n        \"/templates/backlinks.tmpl\", \r\n        \"/templates/default_diff.tmpl\", \r\n        \"/templates/default_edit.tmpl\", \r\n        \"/templates/default_input.tmpl\", \r\n        \"/templates/default_ref.tmpl\", \r\n        \"/templates/default_repr.tmpl\", \r\n        \"/templates/default_view.tmpl\", \r\n        \"/templates/deleted.tmpl\", \r\n        \"/templates/diff.tmpl\"\r\n    ]\r\n};\r\n\r\nquery(request, response);\r\n</pre></div>\r\n\r\nThe `offset` directive can be used to ask infogami to give results from a specific offset.\r\n\r\nThe following query gives the next 10 templates.\r\n\r\n<div class=\"query\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre>\r\nvar request = {\r\n    \"type\": \"/type/template\",\r\n    \"sort\": \"key\",\r\n    \"limit\": 10,\r\n    \"offset\": 10\r\n};\r\n\r\nvar response = {\r\n    \"status\": \"ok\", \r\n    \"result\": [\r\n        \"\\/templates\\/editpage.tmpl\", \r\n        \"\\/templates\\/forgot_password.tmpl\", \r\n        \"\\/templates\\/fullsearch.tmpl\", \r\n        \"\\/templates\\/history.tmpl\", \r\n        \"\\/templates\\/i18n.tmpl\", \r\n        \"\\/templates\\/imageupload.tmpl\", \r\n        \"\\/templates\\/login.tmpl\", \r\n        \"\\/templates\\/login_preferences.tmpl\", \r\n        \"\\/templates\\/notfound.tmpl\", \r\n        \"\\/templates\\/password_mailer.tmpl\"\r\n    ]\r\n};\r\n\r\nquery(request, response);\r\n</pre></div>\r\n\r\n#### Expression AND in queries\r\n\r\nAll the keys in the query other than special directives (`sort`, `limit`, `offset`) are implicitly ANDed.\r\n\r\nFor example, the following query finds all objects having type as `/type/edition` and author as Mark Twain (`/a/OL18319A`).\r\n\r\n<div class=\"query\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre>\r\n\r\nvar request = {\r\n    \"type\": \"/type/edition\",\r\n    \"authors\": \"/a/OL18319A\",\r\n    \"sort\": \"key\",\r\n    \"limit\": 5\r\n};\r\n\r\nvar response =  {\r\n    \"status\": \"ok\", \r\n    \"result\": [\r\n        \"\\/b\\/OL1001932M\", \r\n        \"\\/b\\/OL1016757M\", \r\n        \"\\/b\\/OL1017798M\", \r\n        \"\\/b\\/OL1045540M\", \r\n        \"\\/b\\/OL105166M\"\r\n    ]\r\n};\r\n\r\nquery(request, response)\r\n</pre></div>\r\n\r\n<a name=\"getting\">&nbsp;</a>\r\n### Getting an Object (/get)\r\n\r\nIn Infogami, every object is identified by a unique key. In the example above, we queried the database on an ISBN and were returned the unique key for the edition that matches that ISBN. We can then retrieve the edition with a `get` command:\r\n\r\n<div class=\"query\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre>$ curl http://openlibrary.org/api/get?key=/b/OL1001932M</pre>\r\n</div>\r\n\r\nThis returns:\r\n\r\n<div class=\"response\" style=\"width: 800px; margin-left: 100px;\">\r\n<code class=\"normal\">\r\n{ \"status\": \"ok\",  \"result\": { \"subject_place\": [ \"Venice (Italy)\"],  \"lc_classifications\": [ \"DG674.2 .S3 2005\" ], \"latest_revision\": 1,  \"genres\": [            \"Juvenile literature.\"],  \"title\": \"This is Venice\",  \"languages\": [ { \"key\": \"\\/l\\/eng\" }], \"subjects\": [ \"Venice (Italy) -- Description and travel -- Juvenile literature.\"],  \"publish_country\": \"nyu\", \"by_statement\": \"M. Sasek.\",\"type\": { \"key\": \"\\/type\\/edition\" },  \"revision\": 1, publishers\": [ \"Universe\"],  \"last_modified\": \"2008-04-01T03:28:50.625462\",  \"key\": \"\\/b\\/OL3315616M\",  \"authors\": [ { \"key\": \"\\/a\\/OL1396639A\"            } ],  \"publish_places\": [ \"New York, NY\" ],  \"pagination\": \"56 p. :\",  \"lccn\": [ \"2004110229\" ],  \"notes\": \"\\\"A children's classic\\\"--Cover.\\nOriginally published: New York : Macmillan, 1961.\",  \"number_of_pages\": 56,  \"isbn_10\": [ \"0789312239\" ], publish_date\": \"2005\" }}\r\n</code>\r\n</div>\r\n\r\nBecause this string is hard to read, you may want to add the parameter \"prettyprint=true\" when you are testing your queries. \r\n\r\n<div class=\"query\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre>$ curl http://openlibrary.org/api/get?key=/b/OL1001932M&prettyprint=true</pre>\r\n</div>\r\n\r\nThis returns a more eye-readable version of the same string.\r\n\r\n<div class=\"response\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre># response\r\n     {\r\n       \"status\": \"ok\", \r\n        \"result\": {\r\n        \"subject_place\": \r\n            \"Venice (Italy)\", \r\n        \"lc_classifications\": \r\n            \"DG674.2 .S3 2005\", \r\n        \"latest_revision\": 1, \r\n        \"genres\": [\r\n            \"Juvenile literature.\"\r\n        ], \r\n        \"title\": \"This is Venice\", \r\n        \"languages\": [\r\n            {\r\n                \"key\": \"\\/l\\/eng\"\r\n            }\r\n        ], \r\n        \"subjects\": [\r\n            \"Venice (Italy) -- Description and travel -- Juvenile literature.\"\r\n        ], \r\n        \"publish_country\": \"nyu\", \r\n        \"by_statement\": \"M. Sasek.\", \r\n        \"type\": {\r\n            \"key\": \"\\/type\\/edition\"\r\n        }, \r\n        \"revision\": 1, \r\n        \"publishers\": [\r\n            \"Universe\"\r\n        ], \r\n        \"last_modified\": \"2008-04-01T03:28:50.625462\", \r\n        \"key\": \"\\/b\\/OL3315616M\", \r\n        \"authors\": [\r\n            {\r\n                \"key\": \"\\/a\\/OL1396639A\"\r\n            }\r\n        ], \r\n        \"publish_places\": [\r\n            \"New York, NY\"\r\n        ], \r\n        \"pagination\": \"56 p. :\", \r\n        \"lccn\": [\r\n            \"2004110229\"\r\n        ], \r\n        \"notes\": \"\\\"A children's classic\\\"--Cover.\\nOriginally published: New York : Macmillan, 1961.\", \r\n        \"number_of_pages\": 56, \r\n        \"isbn_10\": [\r\n            \"0789312239\"\r\n        ], \r\n        \"publish_date\": \"2005\"\r\n         }\r\n       }</pre>\r\n</div>\r\n\r\n\r\nThe following example gets the page `/pagelist` using the API.\r\n\r\n<div class=\"query\" style=\"width: 800px; margin-left: 100px;\">\r\n<pre>    $ curl http://openlibrary.org/api/get?key=/pagelist?prettyprint=true\r\n    {\r\n        \"status\": \"ok\", \r\n        \"result\": {\r\n            \"body\": \"{{PageList(\\\"\\/\\\")}}\", \r\n            \"title\": \"Page List\", \r\n            \"last_modified\": \"2008-04-18T09:19:56.978194\", \r\n            \"latest_revision\": 1, \r\n            \"key\": \"\\/pagelist\", \r\n            \"type\": {\"key\": \"\\/type\\/page\"}, \r\n            \"revision\": 1\r\n        }\r\n     }</pre>\r\n\r\n\r\n\r\n\r\n</div>    \r\n\r\nSince the response is in JSON format, the Content-Type is set to `application/json`, which may not be displayed by the browsers as text. To enable that `text=true` must be passed in the query string.\r\n\r\n<a name=\"versions\">&nbsp;</a>\r\n### Queries for Versions (/versions)\r\n\r\nIn Infogami, modification of every object creates a new version of that object. \r\nTo find versions matching a particular query, send a GET request to <http://openlibrary.org/api/versions> with `query` as parameter. The `query` must be a JSON dictionary, just like the things query. The `sort` and `limit` directives work similar to the things query. \r\n\r\nFor example the following query finds the most 10 versions of `/` object. \r\n\r\n<div style=\"margin-left: 100px;\">\r\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"width: 800px\"><tr><td valign=\"top\">\r\n<div class=\"query\">\r\n<pre># Query\r\n    {\r\n        \"key\": \"/\",\r\n        \"limit\": 3,\r\n        \"sort\": \"-created\"\r\n    }</pre>\r\n</div>\r\n\r\n</td>\r\n<td valign=\"top\" class=\"arrow\">&#x21D2;</td>\r\n<td valign=\"top\">\r\n<div class=\"response\">\r\n<pre># Response\r\n    {\r\n        \"status\": \"ok\", \r\n        \"result\": [\r\n            {\r\n                \"comment\": \"\", \r\n                \"created\": \"2008-04-18T15:40:04.279578\", \r\n                \"ip\": \"207.241.226.140\", \r\n                \"author\": \"\\/user\\/webchick\", \r\n                \"thing_id\": 9875590, \r\n                \"key\": \"\\/\", \r\n                \"id\": 9894268, \r\n                \"machine_comment\": null, \r\n                \"revision\": 14\r\n            }, \r\n            {\r\n                \"comment\": \"\", \r\n                \"created\": \"2008-04-18T15:39:30.588136\", \r\n                \"ip\": \"207.241.226.140\", \r\n                \"author\": \"\\/user\\/webchick\", \r\n                \"thing_id\": 9875590, \r\n                \"key\": \"\\/\", \r\n                \"id\": 9894267, \r\n                \"machine_comment\": null, \r\n                \"revision\": 13\r\n            }, \r\n            {\r\n                \"comment\": \"\", \r\n                \"created\": \"2008-04-16T00:18:32.743829\", \r\n                \"ip\": \"207.241.226.140\", \r\n                \"author\": \"\\/user\\/webchick\", \r\n                \"thing_id\": 9875590, \r\n                \"key\": \"\\/\", \r\n                \"id\": 9894257, \r\n                \"machine_comment\": null, \r\n                \"revision\": 12\r\n            }\r\n        ]\r\n    }</pre>\r\n</div>\r\n</td></tr></table>\r\n</div> \r\n\r\n<a name=\"search\">&nsbp;</a>\r\n### Search queries (/search)\r\n\r\n<b>This search API is deprecated and not maintained now. The <a href=\"/dev/docs/api/books\">Open Library Books API</a> can be used for searching for ISBNs or other identifiers. We are working on a new work search API to replace this.</b>\r\n\r\n<del class=\"black\">\r\nThere is an incomplete search API as the final interface has not been decided.  Only rudimentary search functions are supported for now. Development in progress is being discussed in the Open Library bug tracker at https://bugs.launchpad.net/openlibrary/+bug/236947; interested parties are invited to post comments and requests in that tracker item.</del>\r\n\r\nA search API query is a JSON dictionary passed as the \"q\" http parameter.  The dictionary just one meaningful entry, \"query\".  The response is a json object containing a list of openlibrary id's.  The optional argument \"prettyprint\" http parameter controls formatting of the response, as above.  In the example below, the query is \r\n<pre>\r\nhttp://openlibrary.org/api/search?q={\"query\":\"Felix Klein\"}&prettyprint=true\r\n</pre>\r\n\r\n<div style=\"margin-left: 100px;\">\r\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"width: 800px\"><tr><td valign=\"top\">\r\n<div class=\"query\">\r\n<pre># Query\r\n    {\r\n        \"query\": \"Felix Klein\",\r\n    }</pre>\r\n</div>\r\n\r\n</td>\r\n<td valign=\"top\" class=\"arrow\">&#x21D2;</td>\r\n<td valign=\"top\">\r\n<div class=\"response\">\r\n<pre># Response\r\n{\r\n    \"status\": \"ok\", \r\n    \"result\": [\r\n        \"/b/OL1618362M\", \r\n        \"/b/OL3253308M\", \r\n        \"/b/OL2532653M\", \r\n        \"/b/OL2628261M\", \r\n        \"/b/OL5501881M\", \r\n        \"/b/OL1299055M\", \r\n        \"/b/OL2099784M\", \r\n        \"/b/OL2418293M\", \r\n        \"/b/OL3303109M\", \r\n        \"/b/OL4412463M\", \r\n        \"/b/OL5068782M\", \r\n        \"/b/OL5305191M\", \r\n        \"/b/OL5550601M\", \r\n        \"/b/OL5550830M\", \r\n        \"/b/OL5550831M\", \r\n        \"/b/OL5876614M\", \r\n\r\n        \"/b/OL5888524M\", \r\n        \"/b/OL6088137M\", \r\n        \"/b/OL6088190M\", \r\n        \"/b/OL6272774M\"\r\n    ]\r\n}</pre>\r\n</div>\r\n</td></tr></table>\r\n</div>\r\n\r\n### Performance Issues\r\n\r\nTo have a bound on the amount of resources consumed by a query, the runtime of each query is limited to 60 sec. Any query that takes longer is aborted.\r\n\r\n<br /><br /><br />"}, "title": "Open Library JSON API", "key": "/dev/docs/json_api", "type": {"key": "/type/page"}, "m": "edit", "latest_revision": 7, "revision": 7, "created": {"type": "/type/datetime", "value": "2009-05-21T02:51:49.182564"}, "last_modified": {"type": "/type/datetime", "value": "2022-09-05T19:11:53.170464"}}