'''WARNING: This document is now deprecated.''' The official documentation has been moved to https://dashboard.snapcraft.io/docs/ <> = Click Package Index = ''Contact: James Tait (JamesTait)'' * [[https://search.apps.ubuntu.com/api/v1/search|Click Package Search]] * Lucene-backed repository for Click Package metadata * Public front-end will serve as access control, apply sane defaults and massage request and response for ease of use. * Interfaces with: * Software Centre Agent * App developer defines app in Software Centre website * App developer uploads packaged app * Software Centre Agent pushes metadata to Click Package Index * Metadata harvested from Click Manifest * Verified and corrected by developer * Store Scope * "Surfacing", i.e. first view of Store Scope before querying * "Search", i.e. list of packages that match search criteria * "Detail", i.e. full metadata for a given package * WebDM * "Search", i.e. list of packages that match search criteria * "Detail", i.e. full metadata for a given package == The Short and Skinny == The API is designed to be discoverable and simple to use. All you really need is curl and an understanding of JSON, though Python and a tool such as `jq` can help. First we'll set up the values for a couple of headers we're going to send with our requests, to make sure we get packages relevant to our environment. {{{ $ ARCH=$(dpkg-architecture -qDEB_HOST_ARCH) $ FRAMEWORKS=$(for file in /usr/share/click/frameworks/*.framework; do basename $file .framework; done | paste -sd ',') $ echo $ARCH $FRAMEWORKS amd64 ubuntu-sdk-13.10,ubuntu-sdk-14.04-dev1,ubuntu-sdk-14.04,ubuntu-sdk-14.04-html-dev1,ubuntu-sdk-14.04-html,ubuntu-sdk-14.04-papi-dev1,ubuntu-sdk-14.04-papi,ubuntu-sdk-14.04-qml-dev1,ubuntu-sdk-14.04-qml }}} Next, we query the API root and find the search endpoint - unlikely to change, but you never know! Here we use `jq` to filter the response down to just the element were interested in: {{{ $ curl -s -H "X-Ubuntu-Architecture: $ARCH" -H "X-Ubuntu-Frameworks: $FRAMEWORKS" -H 'Accept: application/hal+json' 'https://search.apps.ubuntu.com/api/v1' | jq '._links.search.href' "https://search.apps.ubuntu.com/api/v1/search{?q}" }}} Now we issue a search query, expanding the returned URL template to provide our query string. Again, `jq` is used to cut straight to the embedded Package resources, which are trimmed right down to the essentials in search results. {{{ $ curl -s -H "X-Ubuntu-Architecture: $ARCH" -H "X-Ubuntu-Frameworks: $FRAMEWORKS" -H 'Accept: application/hal+json' 'https://search.apps.ubuntu.com/api/v1/search?q=xkcd' | jq '._embedded["clickindex:package"]' [ { "prices": {}, "publisher": "Dimitri John Ledkov", "name": "net.launchpad.click-webapps.xkcd", "title": "xkcd", "icon_url": "https://myapps.developer.ubuntu.com/site_media/appmedia/2013/09/xkcd-64.png", "price": 0, "content": "application", "ratings_average": 3.83, "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/package/net.launchpad.click-webapps.xkcd" } } }, { "prices": {}, "publisher": "Hansueli Burri", "name": "com.ubuntu.developer.hansueli.burri.xkcd-viewer", "title": "XKCD Viewer", "icon_url": "https://myapps.developer.ubuntu.com/site_media/appmedia/2013/10/Logo.png", "price": 0, "content": "application", "ratings_average": 2.2, "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/package/com.ubuntu.developer.hansueli.burri.xkcd-viewer" } } }, { "prices": {}, "publisher": "Theo Friberg", "name": "com.ubuntu.developer.theo.friberg.comicshelf", "title": "ComicShelf", "icon_url": "https://myapps.developer.ubuntu.com/site_media/appmedia/2014/10/logo_comic_shelf_256.png", "price": 0, "content": "application", "ratings_average": 0, "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/package/com.ubuntu.developer.theo.friberg.comicshelf" } } } ] }}} Now we get the complete package details for one of the results using the URL in its `_links.self.href` property. {{{ $ curl -s -H "X-Ubuntu-Architecture: $ARCH" -H "X-Ubuntu-Frameworks: $FRAMEWORKS" -H 'Accept: application/hal+json' 'https://search.apps.ubuntu.com/api/v1/package/net.launchpad.click-webapps.xkcd' | jq '.' { "architecture": [ "all" ], "alias": null, "allow_unauthenticated": false, "click_version": "0.1", "changelog": "* Add audio & video policy groups by default.\n* Enable back & forward buttons.\n* Switch to webapp-container.\n", "date_published": "2013-09-13T17:52:17.675494Z", "license": "GNU GPL v3", "name": "net.launchpad.click-webapps.xkcd", "publisher": "Dimitri John Ledkov", "content": "application", "download_url": "https://public.apps.ubuntu.com/download/net.launchpad.click-webapps/xkcd/net.launchpad.click-webapps.xkcd_5_all.click", "binary_filesize": 15302, "icon_url": "https://myapps.developer.ubuntu.com/site_media/appmedia/2013/09/xkcd-64.png", "support_url": "https://bugs.launchpad.net/click-webapps/+filebug", "title": "xkcd", "ratings_average": 3.83, "id": 70, "whitelist_country_codes": [], "website": "https://launchpad.net/click-webapps", "last_updated": "2014-03-12T21:07:55.420513Z", "video_embedded_html_urls": [], "keywords": [], "video_urls": [], "terms_of_service": "", "screenshot_url": "https://myapps.developer.ubuntu.com/site_media/appmedia/2013/09/xkcd-1.png", "developer_name": "Dimitri John Ledkov", "revision": 1, "version": "5", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/package/net.launchpad.click-webapps.xkcd" }, "curies": [ { "templated": true, "name": "clickindex", "href": "https://search.apps.ubuntu.com/docs/v1/relations.html{#rel}" } ] }, "company_name": "", "department": [ "communication" ], "screenshot_urls": [ "https://myapps.developer.ubuntu.com/site_media/appmedia/2013/09/xkcd-1.png" ], "status": "Published", "download_sha512": "3c5bc7af4dbaf941465e8cc842b2b8a4e96c76084ad68052623147612811db5e455757bc5266deeea4ef0c1d7e07994a3881200f296cbf022c37a16efcf902b4", "description": "A webcomic of romance, sarcasm, math, and language.\nBrowse latest and past XKCD comics in-style, with handy touch friendly link to read comics' ALT text.", "click_framework": [ "ubuntu-sdk-13.10" ], "price": 0, "translations": {}, "framework": [ "ubuntu-sdk-13.10" ], "prices": {}, "icon_urls": { "16": "https://myapps.developer.ubuntu.com/site_media/appmedia/2013/09/xkcd-16.png", "64": "https://myapps.developer.ubuntu.com/site_media/appmedia/2013/09/xkcd-64.png", "32": "https://myapps.developer.ubuntu.com/site_media/appmedia/2013/09/xkcd-32.png", "128": "https://myapps.developer.ubuntu.com/site_media/appmedia/2013/09/xkcd-128.png" }, "blacklist_country_codes": [], "package_name": "xkcd", "origin": "net.launchpad.click-webapps" } }}} At this point you're ready to download the package. You'll need an Ubuntu SSO account to do that, because the download request has to be OAuth-signed, so we need to get a token: {{{ $ curl https://login.ubuntu.com/api/v2/tokens/oauth -d '{"email": "sso.user@example.com", "password": "top-s3kr!t", "token_name": "click_example"}' -H 'Content-Type: application/json' { "openid": "aBc123D", "token_name": "click_example", "date_updated": "2014-12-05T12:30:33.947", "token_key": "sdKJHklmuK77bjb7r6hjHVVVVff76rfjhvjh98bBUbBubbb690njgibJHjKU", "consumer_secret": "lkjlkLBbkjlkjbBUIBIUbUBiuBIubH", "href": "/api/v2/tokens/oauth/sdKJHklmuK77bjb7r6hjHVVVVff76rfjhvjh98bBUbBubbb690njgibJHjKU", "date_created": "2014-12-05T12:30:33.947", "consumer_key": "aBc123D", "token_secret": "lkjIOONobIUblu765bKJB6v77B6vghjhvhgkJNLKJk553jhgNI99BU6NNLyuyrFhhkbl4G" } }}} Then we use this to sign a GET request to the URL in the download_url property of the package response to download the click: {{{ $ python Python 2.7.6 (default, Mar 22 2014, 22:59:56) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from oauthlib.oauth1.rfc5849 import Client >>> import requests >>> >>> client = Client( ... "aBc123D", # consumer_key ... "lkjlkLBbkjlkjbBUIBIUbUBiuBIubH", # consumer_secret ... "sdKJHklmuK77bjb7r6hjHVVVVff76rfjhvjh98bBUbBubbb690njgibJHjKU", # token_key ... "lkjIOONobIUblu765bKJB6v77B6vghjhvhgkJNLKJk553jhgNI99BU6NNLyuyrFhhkbl4G" # token_secret ... ) >>> >>> uri, headers, body = client.sign( ... "https://public.apps.ubuntu.com/download/net.launchpad.click-webapps/xkcd/net.launchpad.click-webapps.xkcd_5_all.click") >>> response = requests.get(uri, headers=headers) >>> >>> with open("net.launchpad.click-webapps.xkcd_5_all.click", "wb") as f: ... f.write(response.content) ... >>> }}} Now we can verify that the download was successful by checking the downloaded file's sha512 hash, which should match that in the download_sha512 property of the Package resource: {{{ $ sha512sum net.launchpad.click-webapps.xkcd_5_all.click 3c5bc7af4dbaf941465e8cc842b2b8a4e96c76084ad68052623147612811db5e455757bc5266deeea4ef0c1d7e07994a3881200f296cbf022c37a16efcf902b4 net.launchpad.click-webapps.xkcd_5_all.click }}} == Schema == === Field Types === || '''Name''' || '''Notes''' || || boolean || True or False. || || date || Date of the format {{{'YYYY-MM-DD"T"hh24:mm:ss[.nnn]"Z"'}}}, e.g. {{{'2013-06-27T12:39:45.776Z'}}} || || float || Floating point number. || || long || Long integer. || || object || JSON object. || || string || Untokenised text. || || text_''lang''|| Localised tokenised text. Language-specific tokenizer where possible, {{{StandardTokenizer}}} otherwise, case-insensitive stop words, down-casing, protected words and minimal stemming. Query-time synonyms. See [[#Localisation|Localisation]] below.|| || url || Link to a retrievable resource. || === Resources === <> ==== Package ==== || '''Name''' || '''Type''' || '''Multi-value''' || '''Searchable''' || '''Retrievable''' || '''Required''' || '''Translatable''' || '''Notes''' || || ''name'' || ''string'' || ''false'' || ''true'' || ''true'' || ''true'' || ''false'' || e.g. org.example.my_app || || alias || string || false || true || true ||false || false || An alias for the name, another name by which the package is known. May be null if there is no alias. There will only be one package with a given alias. || || architecture || string || true || true || true || false || false || '''Deprecated''' This field should not be used as a search parameter. The client architecture should be passed in the X-Ubuntu-Architecture header instead. If both the header and the parameter are present, the header will take precedence. || || binary_filesize || long || false || false || true || false || false || Size of the downloadable package, in bytes. || || blacklist_country_codes || string || true || true || false || false || false || || || changelog || text_en || false || true || true || false || false || List of changes in this version. || || click_version || string || false || true || true || true || false || || || company_name || text_en || false || true || true || false || false || || || content || string || false || true || true || true || false || application|scope || || date_published || date || false || true || true || false || false || Date of publication. || || department || string || true || true || true || false || false || See the [[https://wiki.ubuntu.com/SoftwareCenter#Genre|Software Centre Genre Spec]] and the [[http://standards.freedesktop.org/menu-spec/menu-spec-1.0.html#category-registry|freedesktop.org Desktop Menu Spec]] || || description || text_en || false || true || true || true || true || Full description of the app's functionality. || || developer_name || text_en || false || true || true || false || false || The full name of the developer profile which uploaded the package. || || download_sha512 || string || false || true || true || true || false || SHA512 hash of the click package. || || download_url || url || false || false || true || true || false || || || framework || string || true || true || true || true || false || '''Deprecated''' This field should not be used as a search parameter. The list of supported frameworks should be passed as a comma-separated list in the X-Ubuntu-Frameworks header instead. If both the header and the parameter are present, the header will take precedence. || || icon_url || url || false || false || true || false || false || URL to a 64x64px PNG image to use as an application icon, e.g. in menus. || || icon_urls || object || true || true || true || false || false || Key is icon size in pixels (icons are assumed to be square); value is a URL. || || keywords || text_en || true || true || true || false || true || || || last_updated || date || false || true || true || false || false || Date of the most recent uploaded binary. || || license || text_en || false || true || true || true || false || License under which the software is made available. || || origin || string || false || ? || true ||true || false || Distinguishes packages that have the same package_name. || || package_name || string || false || true || true || true || false || Un-namespaced package name. May be shared by many packages, which will be distinguished by their origin || || price || float || false || true || true || false || true (currencies) || '''Deprecated''' Price in USD. Use {{{prices}}} instead. || || prices || object || true || true || true || false || false || Key is ISO4217 currency code; value is a float. || || publisher || text_en || false || true || true || false || false || The company name or the full name of the developer profile which uploaded the package if the company name is not available. || || ratings_average || float || false || true || true || false || false || Average user rating for this package. || || revision || long || false || true || true || true || false || Uniquely identifies each bnary upload of a package. || || sequence || long || false || true || true || true || false || '''Deprecated''' Uniquely identifies each bnary upload of a package. Use {{{revision}}} instead. || || screenshot_url || url || false || false || true || false || false || URL to a screen shot. || || screenshot_urls || url || true || false || true || false || false || List of URLs to other screenshots. || || status || string || false || false || true || true || false || The status of the package. Valid values are `Published` and `Quarantined`. || || support_url || url || false || false || true || false || true || URL to localised support channel. || || tos_url || url || false || false || true || false || true || URL to localised ToS. || || title || text_en || false || true || true || true || true || Display name, as presented in menus, store, scopes. || || translations || object || false || true || true || false || false || Translated values for the other properties of this package. Key is the ISO3166 language code. Value is an object containing the translated values to be overlaid. || || version || string || false || true || true || true || false || || || video_urls || url || true || false || true || false || false || || || website || url || false || false || true || false || true || || || whitelist_country_codes || string || true || true || false || false || false || || <> ==== Department ==== || '''Name''' || '''Type''' || '''Multi-value''' || '''Searchable''' || '''Retrievable''' || '''Required''' || '''Translatable''' || '''Notes''' || || ''slug'' || ''string'' || ''false'' || ''true'' || ''true'' || ''true'' || ''false'' || || || name || text_en || false || true || true || true || true || || || translations || object || false || true || true || false || false || Translated values for the other properties of this package. Key is the ISO3166 language code. Value is an object containing the translated values to be overlaid. || <> ==== Highlight ==== || '''Name''' || '''Type''' || '''Multi-value''' || '''Searchable''' || '''Retrievable''' || '''Required''' || '''Translatable''' || '''Notes''' || || ''slug'' || ''string'' || ''false'' || ''true'' || ''true'' || ''true'' || ''false'' || || || name || text_en || false || true || true || true || true || || || description || text_en || false || true || true || true || true || A short description or tagline for this highlight, e.g. `top-apps` might have a `name` of "Top Apps" and a `description` of "Our pick of the best apps in the Store." || || translations || object || false || true || true || false || false || Translated values for the other properties of this package. Key is the ISO3166 language code. Value is an object containing the translated values to be overlaid. || == Localisation == Fields marked as translatable will have localised variants whose field name is suffixed with one of the following country codes: || '''Suffix''' || '''Language''' || '''Analyzer/Language''' || || ar || Arabic || arabic || || az || Azerbaijani || standard || || bg || Bulgarian || bulgarian || || bn || Bengali || standard || || bs || Bosnian || standard || || ca || Catalan || snowball/Catalan || || cs || Czech || czech || || cy || Welsh || standard || || da || Danish || snowball/Danish || || de || German || snowball/German || || el || Greek || greek || || en || English || snowball/English || || en-gb || British English || snowball/English || || eo || Esperanto || standard || || es || Spanish || snowball/Spanish || || es-ar || Argentine Spanish || snowball/Spanish || || es-mx || Mexican Spanish || snowball/Spanish || || es-ni || Nicaraguan Spanish || snowball/Spanish || || et || Estonian || standard || || eu || Basque || snowball/Basque || || fa || Persian || persian || || fi || Finnish || snowball/Finnish || || fr || French || snowball/French || || fy-nl || Frisian || standard || || ga || Irish || standard || || gl || Galician || galician || || he || Hebrew || standard || || hi || Hindi || hindi || || hr || Croatian || standard || || hu || Hungarian || snowball/Hungarian || || id || Indonesian || indonesian || || is || Icelandic || standard || || it || Italian || snowball/Italian || || ja || Japanese || cjk || || ka || Georgian || standard || || kk || Kazakh || standard || || km || Khmer || standard || || kn || Kannada || standard || || ko || Korean || standard || || lt || Lithuanian || standard || || lv || Latvian || standard || || mk || Macedonian || standard || || ml || Malayalam || standard || || mn || Mongolian || standard || || nb || Norwegian Bokmål || snowball/Norwegian || || ne || Nepali || standard || || nl || Dutch || snowball/Dutch || || nn || Norwegian Nynorsk || snowball/Norwegian || || pa || Punjabi || standard || || pl || Polish || standard || || pt || Portuguese || snowball/Portuguese || || pt-br || Brazilian Portuguese || snowball/Portuguese || || ro || Romanian || snowball/Romanian || || ru || Russian || snowball/Russian || || sk || Slovak || standard || || sl || Slovenian || standard || || sq || Albanian || standard || || sr || Serbian || standard || || sr-latn || Serbian Latin || standard || || sv || Swedish || snowball/Swedish || || sw || Swahili || standard || || ta || Tamil || standard || || te || Telugu || standard || || th || Thai || thai || || tr || Turkish || snowball/Turkish || || tt || Tatar || standard || || uk || Ukrainian || standard || || ur || Urdu || standard || || vi || Vietnamese || standard || || zh-cn || Simplified Chinese || chinese || || zh-tw || Traditional Chinese || chinese || For queries: * If the query specifies a localisation (e.g. `q=description_en:foo`), we will use it. * Similarly, if a specific localised result field is requested (e.g. `fields=description_en`), we will use it. * In the general case, clients should use the non-localised field name in queries (`q=description`) and result fields (`fields=description`) and provide an `Accept-Language` header, which we will use to choose the localised variant. * If the request specifies an alternative localisation via the `lang` query parameter (e.g. `lang=en`) we will use that in preference to the language in the `Accept-Language` header. * If the request specifies a localisation which is unavailable, the English localisation will be returned. This keeps the query API flexible, but avoids unnecessary complexity in the client for the general case. We'll need to be wary of caching, in particular - `Vary: Accept-Language` and `ETag` headers will be required at least. == Client Platform Properties == The client's architecture and supported frameworks are platform properties - the user isn't going to enter these in the dash, they're intrinsic to the device and aren't going to change from one search to the next. They're also not strict requirements - the intended meaning is "this device supports these features", not "all of these features must be required by the package". For example, a search for `keywords:maps,title:google` should return Google Maps, but not Bing Maps. On the other hand, a search for `architecture:armhf` isn't saying "only give me packages for armhf", but "my architecture is armhf - do the hard work for me and discard anything I can't use", and would also return packages with `architecture:all`; and a search specifying `framework:ubuntu-sdk-13.10,framework:ubuntu-sdk-14.04` isn't expecting to find packages that require *both* frameworks, but is instead saying "I support both of these and nothing else - do the hard work for me and discard anything I can't use". They're not strict requirements on the package - all conditions don't have to be met - but a statement about the execution environment. The search is additive, i.e. specifying more values for these properties should *add* results, not take them away. These properties will be passed as request headers, similarly to the user's language setting, as outlined below. === Client Architecture === The client's architecture will be passed as a single string in the `X-Ubuntu-Architecture` request header. Recognised values are: `armhf`, `i386`, `x86_64`. The value provided will be combined combined with the value `all` by the server, such that the result will include packages that specifically target the client architecture, and those that have no architecture-specific components. For example, the request header: `X-Ubuntu-Architecture: armhf` would match the following packages: {{{ [ { "name": "org.example.awesomelauncher", "title": "Awesome Launcher", "publisher": "Awesome Widget Company", "architecture": ["armhf", "i386"], "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomelauncher/icons/icon16.png" }, { "name": "org.example.awesomewidget", "title": "Awesome Widget", "publisher": "Awesome Widget Company", "architecture": ["all"], "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomewidget/icons/icon16.png" } ] }}} but not the following: {{{ [ { "name": "org.example.awesomelauncher", "title": "Awesome Launcher", "publisher": "Awesome Widget Company", "architecture": ["i386"], "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomelauncher/icons/icon16.png" }, { "name": "org.example.awesomewidget", "title": "Awesome Widget", "publisher": "Awesome Widget Company", "architecture": ["x86_64"], "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomewidget/icons/icon16.png" } ] }}} === Frameworks === The frameworks supported by the client will be passed as a comma-separated list of values in the the `X-Ubuntu-Frameworks` request header. The values provided will be used in an exact match query, such that the frameworks listed by packages in the result will be a subset of those provided by the client. For example, the request header: `X-Ubuntu-Frameworks: ubuntu-sdk-13.10,ubuntu-sdk-14.04` would match the following packages: {{{ [ { "name": "org.example.awesomelauncher", "title": "Awesome Launcher", "publisher": "Awesome Widget Company", "framework": ["ubuntu-sdk-13.10"], "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomelauncher/icons/icon16.png" }, { "name": "org.example.awesomewidget", "title": "Awesome Widget", "publisher": "Awesome Widget Company", "framework": ["ubuntu-sdk-14.04"], "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomewidget/icons/icon16.png" } ] }}} but not: {{{ [ { "name": "org.example.awesomelauncher", "title": "Awesome Launcher", "publisher": "Awesome Widget Company", "framework": ["ubuntu-sdk-13.10", "fictional-framework-13.10"], "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomelauncher/icons/icon16.png" }, { "name": "org.example.awesomewidget", "title": "Awesome Widget", "publisher": "Awesome Widget Company", "framework": ["ubuntu-sdk-14.04-dev"], "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomewidget/icons/icon16.png" } ] }}} === Confinement === The client can specify a confinement level, passed as a single string in the `X-Ubuntu-Confinement` request header. Recognised values are: `strict`, `devmode`. If the header is not specified, the `strict` level will be assumed. When `devmode` is passed, the returned revisions will be the greatest available matching revision independently of its `confinement` value (ie. you can get a `strict` or `devmode` revision, the greatest). On the other hand, when filtering by `strict` confinement (the default), only revisions whose `confinement` value is set as `strict` will be returned. === Client Device Channel === The client can specify a device channel, passed as a single string in the `X-Ubuntu-Device-Channel` request header. Recognised values are: `stable`, `candidate`, `beta`, `alpha`. If this header is not specified, the `stable` channel will be assumed. This channel will be used as the base channel when responding queries to the index (combined with the other provided headers). When the header is explicitly provided, it is assumed the client has channel support implemented. === Working with an specific store === The X-Ubuntu-Store header allows to control the results of API calls so that they are narrowed to an specific store. The following example will return results for "xkcd" which match applications from "x-store": {{{ curl -s -H "X-Ubuntu-Store: x-store" -H 'Accept: application/hal+json' 'https://search.apps.ubuntu.com/api/v1/search?q=xkcd' }}} When this header is missing from the request, the store is always assumed to be the Ubuntu store. === Filtering for a supported release === The X-Ubuntu-Release header allows to control the results of API calls so that they are narrowed to an specific supported release. The following example will return results for "xkcd" which support the 15.04 release: {{{ curl -s -H "X-Ubuntu-Release: 15.04" -H 'Accept: application/hal+json' 'https://search.apps.ubuntu.com/api/v1/search?q=xkcd' }}} == Tracking device data in CPI requests == CPI provides the possibility to track device data along API requests, such data should be added into API requests as HTTP headers. Below is a list of all the possible information that can be tracked for a particular device, alongside with its respective header: || '''What''' || '''Header''' || '''Notes''' || || Device unique ID || X-Device-Id || Device's unique ID || || Owner || Authorization || The owner's Open ID is extracted from the OAuth signed request. || || CPU || X-Device-Cpu || A string describing the CPU || || GPU || X-Device-Gpu || A string describing the GPU || || Available RAM || X-Device-Ram || Integer value in MB || || Disk size || X-Device-Disk || Integer value in MB || || Device Architecture || X-Device-Architecture || Architecture identifier string (e.g "armhf") || || Installed frameworks || X-Device-Frameworks || Comma separated list of frameworks (e.g. "ubuntu-sdk-13.10,ubuntu-sdk-14.10") || || Kernel || X-Device-Kernel || A string describing the device's Kernel || || Vendor || X-Vendor-Id || Vendor's unique identifier || || OTA || X-Device-Ota || OTA string identifier (e.g. r1) || || Secure boot || X-Device-Secure-Boot || true/false || || Release || X-Device-Release || Release identifier string || || Untampered || X-Device-Untampered || true/false || Note that all of these headers are optional and do not affect the CPI API in any way. == API == The API is intended to be a hypermedia API, i.e. its architecture is similar to that of the World Wide Web. It should be easy to explore using a web browser and the client shouldn't be required to construct any links itself. The guiding principles are: * JSON-based * Discoverable * Browseable === Response Format === Responses will be formatted as [[http://tools.ietf.org/html/draft-kelly-json-hal-06|Hypertext Application Language]] documents and will have a content type of `application/hal+json`. Responses will include navigation links and embedded resources where applicable. === Relation Types === Embedded and linked resources will be identified by the following relation types: <> '''`clickindex:package`''' Indicates the embedded or linked resource is a [[#resource_package|Package]] resource or list of Package resources directly corresponding to the current document. Examples include Packages within a Department or Highlight, and Packages that match a Search request. <> '''`clickindex:channelpackage`''' Indicates the embedded or linked resource is a [[#resource_package|Package]] resource for a specific channel. These resources are embedded in Package resources, and include a subset of the package fields identifying the specific version in a particular channel, besides providing the link to the full Package information in that channel. <> '''`clickindex:department`''' Indicates the embedded or linked resource is a [[#resource_department|Department]] resource or list of Department resources. Examples include the Departments hierarchy in the Root API resource and sub-departments in the Department resource. <> '''`clickindex:departments`''' Indicates the embedded or linked resource is a hierarchical structure of [[#resource_department|Department]] resources. <> '''`clickindex:highlight`''' Indicates the embedded or linked resource is a [[#resource_highlight|Highlight]] resource. Examples include the list of top-level Highlights in the Root API resource and per-department Highlights in the Department resource. <> '''`clickindex:highlights`''' Indicates the embedded or linked resource is a collection of top-level [[#resource_highlight|Highlight]] resources. <> '''`clickindex:recommendation`''' Indicates the embedded or linked resource is a [[#resource_package|Package]] resource or list of Package resources not directly corresponding to the current document, but are suggested possible matches. Examples include Packages that almost match or offer an alternative to a Search request. === Pagination of Collections === Large collection responses will be paginated. Pagination links will be included the the `_links` property of the collection resource using the standard IANA-registered relation types `first`, `prev`, `next` and `last`. The default page size is 100 items, configurable via the `size` request parameter. Page selection is via the `page` request parameter, and counter is 1-based. === API Root === `/api/v1` Provides clickable links to the other endpoints for discoverability. ==== Request ==== {{{ GET /api/v1 HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/hal+json X-Ubuntu-Frameworks: ubuntu-sdk-13.10,ubuntu-sdk-14.04-dev X-Ubuntu-Architecture: armhf }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/hal+json; charset=utf-8 { "_links": { "curies": [ { "name": "clickindex", "href": "https://search.apps.ubuntu.com/docs/v1/relations.html{#rel}", "templated": true } ], "self": { "href": "https://search.apps.ubuntu.com/api/v1" }, "search": { "title": "Search", "href": "https://search.apps.ubuntu.com/api/v1/search{?q}", "templated": true }, "clickindex:package": { "title": "Package", "href": "https://search.apps.ubuntu.com/api/v1/package/{name}", "templated": true }, "clickindex:highlights": { "title": "Highlights", "href": "https://search.apps.ubuntu.com/api/v1/highlights" }, "clickindex:highlight": { "title": "Highlight", "href": "https://search.apps.ubuntu.com/api/v1/highlights/{slug}", "templated": true }, "clickindex:departments": { "title": "Departments", "href": "https://search.apps.ubuntu.com/api/v1/departments" }, "clickindex:department": { "title": "Department", "href": "https://search.apps.ubuntu.com/api/v1/departments/{slug}", "templated": true }, "clickindex:channels": { "title": "Channel Collection", "href": "https://search.apps.ubuntu.com/api/v1/channels" } }, "_embedded": { "clickindex:department": [ { "name": "Games", "slug": "games", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/games" } }, "has_children": true, "_embedded": { "clickindex:department": [ { "name": "Board Games", "slug": "games_board-games", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/games_board-games" } } } ] } }, { "name": "Graphics", "slug": "graphics", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/graphics" } }, "has_children": true, "_embedded": { "clickindex:department": [ { "name": "Drawing", "slug": "graphics_drawing", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/graphics_drawing" } } } ] } }, { "name": "Internet", "slug": "internet", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/internet" } }, "has_children": true, "_embedded": { "clickindex:department": [ { "name": "Chat", "slug": "internet_chat", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/internet_chat" } } }, { "name": "Mail", "slug": "internet_mail", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/internet_mail" } } }, { "name": "Web Browsers", "slug": "internet_web-browsers", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/internet_web-browsers" } } } ] } } ], "clickindex:highlight": [ { "name": "Top Apps", "slug": "top-apps", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/highlights/top-apps" } }, "_embedded": { "clickindex:package": [ { "_links": { "self": {"href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomelauncher"} }, "name": "org.example.awesomelauncher", "title": "Awesome Launcher", "publisher": "Awesome Widget Company", "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomelauncher/icons/icon16.png" }, { "_links": { "href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomewidget" }, "name": "org.example.awesomewidget", "title": "Awesome Widget", "publisher": "Awesome Widget Company", "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomewidget/icons/icon16.png" } ] } }, { "name": "Most Purchased", "slug": "most-purchased", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/highlights/most-purchased" } }, "_embedded": { "clickindex:package": [ { "_links": { "self": {"href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomelauncher"} }, "name": "org.example.awesomelauncher", "title": "Awesome Launcher", "publisher": "Awesome Widget Company", "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomelauncher/icons/icon16.png" }, { "_links": { "href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomewidget" }, "name": "org.example.awesomewidget", "title": "Awesome Widget", "publisher": "Awesome Widget Company", "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomewidget/icons/icon16.png" } ] } }, { "name": "New Releases", "slug": "new-releases", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/highlights/new-releases" } }, "_embedded": { "clickindex:package": [ { "_links": { "self": {"href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomelauncher"} }, "name": "org.example.awesomelauncher", "title": "Awesome Launcher", "publisher": "Awesome Widget Company", "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomelauncher/icons/icon16.png" }, { "_links": { "href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomewidget" }, "name": "org.example.awesomewidget", "title": "Awesome Widget", "publisher": "Awesome Widget Company", "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomewidget/icons/icon16.png" } ] } }, { "name": "Mark's Choice", "slug": "marks-choice", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/highlights/marks-choice" } }, "_embedded": { "clickindex:package": [ { "_links": { "self": {"href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomelauncher"} }, "name": "org.example.awesomelauncher", "title": "Awesome Launcher", "publisher": "Awesome Widget Company", "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomelauncher/icons/icon16.png" }, { "_links": { "href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomewidget" }, "name": "org.example.awesomewidget", "title": "Awesome Widget", "publisher": "Awesome Widget Company", "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomewidget/icons/icon16.png" } ] } } ] } } }}} === Search === <> `/api/v1/search` Search the index for packages. Queries are specified in the `q` query parameter. Search terms may be entered unqualified, in which case they will be matched against the localised title, description and keywords fields. * Example:: `q=awesome` Alternatively, search terms may be qualified by prefixing them with a field name and a colon. * Example:: `q=title:awesome`. Searches may be performed against several fields, by separating the search terms with commas. * Example:: `q=awesome,title:widget` Terms to be matched against the same field should be separated by a single space. * Example:: `q=title:awesome widget` Search terms may contain wildcards: `?` will match any single character, while `*` will match zero or more characters. * Example:: `q=title:a* widg?t` Search terms may specify an exact phrase that must be matched by surrounding it with double-quotes (`"`). This will also disable processing of wildcards. * Example:: `q="awesome widget"` The list of fields to return in results can be specified in the `fields` parameter. This defaults to `name`, `title`, `publisher`, `price`, `content` and `icon_url`, and additionally `architecture` if no architecture was specified in the request. The URL to the package resource will be included in all responses. * Example:: `q=awesome&fields=title,publisher` Clients should indicate the desired localisation as described in [[#Localisation|Localisation]]. ==== Request ==== {{{ GET /api/v1/search?q=description:common&page=3&size=1 HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/hal+json Accept-Language: en X-Ubuntu-Frameworks: ubuntu-sdk-13.10,ubuntu-sdk-14.04-dev X-Ubuntu-Architecture: armhf X-Ubuntu-Device-Channel: stable }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/hal+json; charset=utf-8 Vary: Accept-Language { "_links": { "curies": [ { "name": "clickindex", "href": "https://search.apps.ubuntu.com/docs/v1/relations.html{#rel}", "templated": true } ], "self": {"href": "https://search.apps.ubuntu.com/api/v1/search?q=description:common&page=3&size=1"}, "first": {"href": "https://search.apps.ubuntu.com/api/v1/search?q=description:common&page=1&size=1"}, "prev": {"href": "https://search.apps.ubuntu.com/api/v1/search?q=description:common&page=2&size=1"}, "next": {"href": "https://search.apps.ubuntu.com/api/v1/search?q=description:common&page=4&size=1"}, "last": {"href": "https://search.apps.ubuntu.com/api/v1/search?q=description:common&page=9&size=1"} }, "_embedded": { "clickindex:package": [ { "_links": { "self": {"href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomelauncher"} }, "name": "org.example.awesomelauncher", "title": "Awesome Launcher", "publisher": "Awesome Widget Company", "content": "application", "revision": 11, "version": "1.1", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomelauncher/icons/icon16.png" }, { "_links": { "href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomewidget" }, "name": "org.example.awesomewidget", "title": "Awesome Widget", "publisher": "Awesome Widget Company", "content": "application", "revision": 2, "version": "0.3", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomewidget/icons/icon16.png" } ], "clickindex:department": [ { "name": "Accessories", "slug": "accessories", "_links": { "self": {"href": "https://search.apps.ubuntu.com/api/v1/departments/accessories"} }, "has_children": true } ], "clickindex:recommendation": [ { "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/package/org.otherexample.app1" } }, "content": "application", "revision": 1, "version": "1", "price": 0, "prices": { "USD": 0 }, "icon_url": "http://otherexample.org/media/app1/icons/icon16.png", "title": "Awesome Recommended App 1", "name": "org.otherexample.app1", "publisher": "Another Example Company" }, { "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/package/org.otherexample.app2" } }, "content": "application", "revision": 4, "version": "1.3", "price": 0, "prices": { "USD": 0 }, "icon_url": "http://otherexample.org/media/app2/icons/icon16.png", "title": "Awesome Recommended App 2", "name": "org.otherexample.app2", "publisher": "Another Example Company" }, { "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/package/org.otherexample.app3" } }, "content": "application", "revision": 2, "version": "1", "price": 0, "prices": { "USD": 0 }, "icon_url": "http://otherexample.org/media/app3/icons/icon16.png", "title": "Awesome Recommended App 3", "name": "org.otherexample.app3", "publisher": "Another Example Company" } ] } } }}} === Package Details === <> `/api/v1/package` Requests details for a specific package. Cleans the query string to ensure the user cannot be tricked into installing the wrong package, and enforces a single item in the response. ==== Request ==== {{{ GET /api/v1/package/com.ubuntu.developer.jamestait.picturesque-malta HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/hal+json Accept-Language: en X-Ubuntu-Frameworks: ubuntu-sdk-13.10,ubuntu-sdk-14.04-dev X-Ubuntu-Architecture: armhf }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/hal+json; charset=utf-8 Vary: Accept-Language { "architecture": [ "all" ], "department": [ "graphics", "photography" ], "keywords": [ "malta", "photography", "geotagging" ], "company_name": "", "_links": { "self": { "href": "http://localhost:8000/api/v1/package/com.ubuntu.developer.jamestait.picturesque-malta" }, "curies": [ { "templated": true, "name": "clickindex", "href": "http://localhost:8000/docs/v1/relations.html{#rel}" } ] }, "version": "0.1", "revision": 1, "developer_name": "James Tait", "click_version": "0.1", "download_url": "https://public.apps.staging.ubuntu.com/download/com.ubuntu.developer.jamestait/picturesque-malta/com.ubuntu.developer.jamestait.picturesque-malta_0.1_all.click", "changelog": "First version", "binary_filesize": 1514, "screenshot_url": "", "prices": { "USD": 0 }, "terms_of_service": "", "framework": [ "ubuntu-sdk-13.10" ], "content": "application", "price": 0, "description": "Create and share geotagged photos and locations in Malta\nTake photos with your Ubuntu phone, add geolocation tags and share them on Flickr. Browse the built-in map to see the photographs uploaded by others.", "last_updated": "2014-05-20T09:58:04.275350Z", "website": "", "category": "Graphics;Photography", "publisher": "James Tait", "name": "com.ubuntu.developer.jamestait.picturesque-malta", "license": "GNU GPL v3", "date_published": "2014-05-20T10:25:04.178326Z", "support_url": "https://example.com/picturesque-malta", "icon_url": "https://developer.staging.ubuntu.com/site_media/appmedia/2014/05/picturesque-malta.png", "title": "Picturesque Malta", "alias": null, "origin": "com.ubuntu.developer.jamestait", "package_name": "picturesque-malta" } }}} === Package Details for a channel === You could also request package details for a specific channel, different from your device channel: ==== Request ==== {{{ GET /api/v1/package/testingagain.matiasb/stable HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/hal+json Accept-Language: en X-Ubuntu-Frameworks: ubuntu-sdk-14.10 X-Ubuntu-Device-Channel: beta }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/hal+json; charset=utf-8 Vary: Accept-Language { "_links": { "curies": [ { "href": "https://wiki.ubuntu.com/AppStore/Interfaces/ClickPackageIndex#reltype_{rel}", "name": "clickindex", "templated": true } ], "self": { "href": "https://search.apps.staging.ubuntu.com/api/v1/package/testingagain.matiasb/stable" } }, "alias": null, "allow_unauthenticated": false, "architecture": [ "all" ], "binary_filesize": 41854, "blacklist_country_codes": [], "changelog": "", "channel": "stable", "click_framework": [ "ubuntu-sdk-14.10" ], "click_version": "0.1", "company_name": "", "content": "application", "date_published": "2015-05-07T16:12:51.731240Z", "department": [ "productivity" ], "description": "Just another test.\ndescription of testingagain", "developer_name": "Matias Bordese", "download_sha512": "85e47a174a042cf6d48fb20883a963b65f53fa7da90fde05433d7b7733657c05e021e22c3151b686fa2fffad2ce95a32d4e70d6e249721668edbee8ba454a221", "download_url": "https://public.apps.staging.ubuntu.com/download/matiasb/testingagain.matiasb/testingagain.matiasb_0.1_all.click", "framework": [ "ubuntu-sdk-14.10" ], "icon_url": "https://myapps.developer.staging.ubuntu.com/site_media/appmedia/2015/05/bitlbee_no4jgGC.png", "icon_urls": { "256": "https://myapps.developer.staging.ubuntu.com/site_media/appmedia/2015/05/bitlbee_no4jgGC.png" }, "id": 420, "keywords": [], "last_updated": "2015-05-07T16:10:26.903893Z", "license": "Proprietary", "name": "testingagain.matiasb", "origin": "matiasb", "package_name": "testingagain", "price": 0.0, "prices": {}, "publisher": "Matias Bordese", "ratings_average": 0.0, "revision": 1, "screenshot_url": null, "screenshot_urls": [], "status": "Published", "stores": { "ubuntu": { "status": "Published" } }, "support_url": "http://google.com", "terms_of_service": "", "title": "testingagain", "version": "0.1", "video_urls": [], "website": null, "whitelist_country_codes": [] } }}} === Package Details for a revision === You could also request package details for a specific revision. If package and revision are published, no authentication will be required. If revision is not published but approved, the package owner(s) can request details for it but a OAuth signed request will be required. No extra filtering headers are required, and they will be ignored if provided. ==== Request ==== {{{ GET /api/v1/package/testingagain.matiasb/1 HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/hal+json Accept-Language: en }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/hal+json; charset=utf-8 Vary: Accept-Language { ... "is_published": true, ... "revision": 1, ... } }}} If revision is unpublished, OAuth authentication is needed (if invalid or missing, you'll get a not found response): ==== Request ==== {{{ GET /api/v1/package/testingagain.matiasb/2 HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/hal+json Accept-Language: en Authorization: }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/hal+json; charset=utf-8 Vary: Accept-Language { ... "is_published": false, ... "revision": 2, ... } }}} === Departments === `/api/v1/departments` Returns a list of the departments currently used by the packages in the index. Appending department names to the URL allows for drill-down searching. ==== Request ==== {{{ GET /api/v1/departments HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/hal+json Accept-Language: en X-Ubuntu-Frameworks: ubuntu-sdk-13.10,ubuntu-sdk-14.04-dev X-Ubuntu-Architecture: armhf }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/hal+json; charset=utf-8 Vary: Accept-Language { "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments" }, "curies": [ { "name": "clickindex", "href": "https://search.apps.ubuntu.com/docs/v1/relations.html{#rel}" "templated": true } ] }, "_embedded": { "clickindex:department": [ { "name": "Games", "slug": "games", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/games" } }, "has_children": true, "_embedded": { "clickindex:department": [ { "name": "Board Games", "slug": "games_board-games", "has_children": false, "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/games_board-games" } } } ] } }, { "name": "Graphics", "slug": "graphics", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/graphics" } }, "has_children": true, "_embedded": { "clickindex:department": [ { "name": "Drawing", "slug": "graphics_drawing", "has_children": false, "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/graphics_drawing" } } } ] } }, { "name": "Internet", "slug": "internet", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/internet" } }, "has_children": true, "_embedded": { "clickindex:department": [ { "name": "Chat", "slug": "internet_chat", "has_children": false, "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/internet_chat" } } }, { "name": "Mail", "slug": "internet_mail", "has_children": false, "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/internet_mail" } } }, { "name": "Web Browsers", "slug": "internet_web-browsers", "has_children": false, "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/internet_web-browsers" } } } ] } } ] } } }}} ==== Request ==== {{{ GET /api/v1/departments/games HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/hal+json Accept-Language: en X-Ubuntu-Frameworks: ubuntu-sdk-13.10,ubuntu-sdk-14.04-dev X-Ubuntu-Architecture: armhf }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/hal+json; charset=utf-8 Vary: Accept-Language { "_links": { "curies": [ { "name": "clickindex", "href": "https://search.apps.ubuntu.com/docs/v1/relations.html{#rel}", "templated": true } ], "collection": { "href": "https://search.apps.ubuntu.com/api/v1/departments" }, "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/games" } }, "has_children": true, "_embedded": { "clickindex:department": [ { “slug”: “games_board-games”, "name": "Board Games", "has_children": false, "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/games_board-games" } } } ], "clickindex:highlight": [ { "name": "Top Games", "slug": "top-games", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/highlights/top-games" } }, "_embedded": { "clickindex:package": [ { "_links": { "self": {"href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomegame"} }, "name": "org.example.awesomegame", "title": "Awesome Game", "publisher": "Awesome Widget Company", "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomegame/icons/icon16.png" } ] } }, ] } } }}} ==== Request ==== {{{ GET /api/v1/departments/games_board-games HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/hal+json Accept-Language: en X-Ubuntu-Frameworks: ubuntu-sdk-13.10,ubuntu-sdk-14.04-dev X-Ubuntu-Architecture: armhf }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/hal+json; charset=utf-8 Vary: Accept-Language { "name": "Board Games", "slug": "games_board-games", "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/departments/games_board-games" }, "collection": { "href": "https://search.apps.ubuntu.com/api/v1/departments" }, "up": { "href": "https://search.apps.ubuntu.com/api/v1/departments/games" }, "curies": [ { "name": "clickindex", "href": "https://search.apps.ubuntu.com/docs/v1/relations.html{#rel}" "templated": true } ] }, "has_children": false, "_embedded": { "clickindex:package": [ { "_links": { "self": {"href": "https://search.apps.ubuntu.com/api/v1/package/org.example.awesomeboardgame"} }, "name": "org.example.awesomeboardgame", "title": "Awesome Board Game", "publisher": "Awesome Widget Company", "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomeboardgame/icons/icon16.png" } ] } } }}} === Channels === `/api/v1/channels` Returns a list of the available channels. ==== Request ==== {{{ GET /api/v1/channels HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/hal+json Accept-Language: en }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/hal+json; charset=utf-8 Vary: Accept-Language { "_embedded": { "clickindex:channel": [ { "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/channels/candidate" } }, "display_name": "Candidate", "name": "candidate" }, { "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/channels/alpha" } }, "display_name": "Alpha", "name": "alpha" }, { "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/channels/stable" } }, "display_name": "Stable", "name": "stable" }, { "_links": { "self": { "href": "https://search.apps.ubuntu.com/api/v1/channels/beta" } }, "display_name": "Beta", "name": "beta" } ] }, "_links": { "curies": [ { "href": "https://wiki.ubuntu.com/AppStore/Interfaces/ClickPackageIndex#reltype_{rel}", "name": "clickindex", "templated": true } ], "self": { "href": "https://search.apps.ubuntu.com/api/v1/channels" } } } }}} === Highlights === `/api/v1/highlights` Return a list of ranked "highlighted" packages for the given highlight. An empty search (i.e. `/api/v1/highlights`) will return a list of top-level highlights. The result is in the same format as a standard search. ==== Request ==== {{{ GET /api/v1/highlights/top-apps?page=1&size=1 HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/hal+json Accept-Language: en X-Ubuntu-Frameworks: ubuntu-sdk-13.10,ubuntu-sdk-14.04-dev X-Ubuntu-Architecture: armhf }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/hal+json; charset=utf-8 Vary: Accept-Language { "name": "Top Apps", "slug": "top-apps", "_links": { "curies": [ { "name": "clickindex", "href": "https://search.apps.ubuntu.com/docs/v1/relations.html{#rel}" "templated": true } ], "self": { "href": "https://search.apps.ubuntu.com/api/v1/highlights/top-apps?page=3&size=1" }, "first": { "href": "https://search.apps.ubuntu.com/api/v1/highlights/top-apps?page=1&size=1" }, "prev": { "href": "https://search.apps.ubuntu.com/api/v1/highlights/top-apps?page=2&size=1" }, "next": { "href": "https://search.apps.ubuntu.com/api/v1/highlights/top-apps?page=4&size=1" }, "last": { "href": "https://search.apps.ubuntu.com/api/v1/highlights/top-apps?page=9&size=1" } }, "_embedded": { "clickindex:package": [ { "name": "org.example.awesomelauncher", "title": "Awesome Launcher", "publisher": "Awesome Widget Company", "content": "application", "price": 1.99, "prices": { "USD": 1.99 }, "icon_url": "http://example.org/media/awesomelauncher/icons/icon16.png", "_links": { "self": {"href": "http://search.apps.ubuntu.com/api/v1/package/org.example.awesomelauncher"} } } ] } } }}} === Updates === `/api/v1/click-metadata` Given a list of packages, return metadata for each package available for this device. The list of packages has to be passed as the `name` key of a JSON dictionary in the request body of an HTTP `POST` request. ==== Request ==== {{{ POST /api/v1/click-metadata HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/json Accept-Language: en X-Ubuntu-Frameworks: ubuntu-sdk-13.10,ubuntu-sdk-14.04-dev X-Ubuntu-Architecture: armhf { "name": [ "org.example.awesomelauncher", "org.example.awesomeboardgame", "org.example.unknownapp" ] } }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Vary: Accept-Language,X-Ubuntu-Frameworks,X-Ubuntu-Architecture [ { "anon_download_url": "http://example.org/anon/clicks/awesomelauncher.click", "binary_filesize": 786543, "changelog": "New revision.", "channel": "stable", "content": "application", "department": [ "accessories" ], "download_sha512": "098798c7870e78097f9879987a98798d789e798798c7987b897987e8789a70987d98798758645a564756a86764d76764e76476f476486c674674674876d4874a", "download_url": "http://example.org/clicks/awesomelauncher.click", "icon_url": "http://example.org/media/awesomelauncher/icons/icon16.png", "name": "org.example.awesomelauncher", "origin": "org.example", "package_name": "awesomelauncher", "revision": 1, "sequence": 1, "status": "Published", "title": "Awesome Launcher", "version": "0.3.2beta1" }, { "binary_filesize": 786543, "changelog": "New themes.", "channel": "stable", "content": "application", "department": [ "games", "board-games" ], "download_sha512": "7098a098798c987987d97f7987e98798a987987b988798c879898757576a809788c89798787e97889798f709879a788798b787098a897898989d78897c87e987", "download_url": "http://example.org/clicks/awesomeboardgame.click", "icon_url": "http://example.org/media/awesomeboardgame/icons/icon16.png", "name": "org.example.awesomeboardgame", "origin": "org.example", "package_name": "awesomeboardgame", "revision": 1, "sequence": 1, "status": "Quarantined", "title": "Awesome Board Game", "version": "2.4" } ] }}} Updates will be reported using the device channel by default, but you can also specify a particular channel (different from the device channel) for a given package, for example: ==== Request ==== {{{ POST /api/v1/click-metadata HTTP/1.1 Host: search.apps.ubuntu.com Accept: application/json Accept-Language: en X-Ubuntu-Frameworks: ubuntu-sdk-15.10 X-Ubuntu-Device-Channel: beta { "name": [ "testingagain.matiasb/stable", "com.ubuntu.developer.matiasb.demo1" ] } }}} ==== Response ==== {{{ HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Vary: Accept-Language,X-Ubuntu-Frameworks,X-Ubuntu-Architecture [ { "binary_filesize": 41854, "changelog": "", "channel": "stable", "content": "application", "department": [ "productivity" ], "download_sha512": "85e47a174a042cf6d48fb20883a963b65f53fa7da90fde05433d7b7733657c05e021e22c3151b686fa2fffad2ce95a32d4e70d6e249721668edbee8ba454a221", "download_url": "https://public.apps.staging.ubuntu.com/download/matiasb/testingagain.matiasb/testingagain.matiasb_0.1_all.click", "icon_url": "https://myapps.developer.staging.ubuntu.com/site_media/appmedia/2015/05/bitlbee_no4jgGC.png", "name": "testingagain.matiasb", "origin": "matiasb", "package_name": "testingagain", "revision": 1, "sequence": 1, "status": "Published", "title": "testingagain", "version": "0.1" }, { "binary_filesize": 41843, "changelog": "Changes for 0.21: testing.", "channel": "beta", "content": "application", "department": [ "business" ], "download_sha512": "d64eb0cdaf656e5a8ebfd302afaf0cb1aae240fbd70f1bc9d654472da1b029a40d01d376347dc6f708b6d61d757cd80f3e635a0d538daaedc396cf0bfd89e222", "download_url": "https://public.apps.staging.ubuntu.com/download/com.ubuntu.developer.matiasb/demo1/com.ubuntu.developer.matiasb.demo1_0.21_all.click", "icon_url": "https://myapps.developer.staging.ubuntu.com/site_media/appmedia/2015/05/bitlbee.png", "name": "com.ubuntu.developer.matiasb.demo1", "origin": "com.ubuntu.developer.matiasb", "package_name": "demo1", "revision": 3, "sequence": 3, "status": "Published", "title": "demo1", "version": "0.21" } ] }}}