===== Snaps ===== Introduction ============ The *Snaps API* provides a series of endpoints supporting common actions during the lifetime of a snap package. The *Snaps API* is exposed at the following base URLs: * Staging: https://dashboard.staging.snapcraft.io/dev/api * Production: https://dashboard.snapcraft.io/dev/api Response Format --------------- JSON_ will be returned in all responses from the API, including :ref:`errors`. .. _JSON: http://www.json.org Reference ========= .. _register-name-api: Register a snap name -------------------- .. http:post:: /dev/api/register-name/ :reqheader Authorization: macaroon authorization header with the ``package_register`` permission :query dry_run: (optional) when set, validate the requested snap name but don't register it :json string snap_id: the unique ``snap_id`` associated with this snap (``null`` when ``dry_run`` query parameter is set) :>json string snap_name: matches the requested snap name :status 200: success (when ``dry_run`` query parameter is set) :status 201: success :status 400: error :status 401: authentication required :status 403: authorization failed :status 409: name already owned by the user, name already registered by someone else, or name reserved :status 429: when names are tried to be registered too quickly :status 503: registration failed .. important:: In order to register a snap name the request's authentication macaroon needs to include the ``package_register`` permission. Refer to the :ref:`macaroon-api` API for information on how to request a macaroon with the right permissions. .. note:: The ``is_private`` parameter is used to indicate the privacy setting for the initial push. This setting can be changed at any later time. The ``dry_run`` query parameter is used to test if the name is valid and currently available. It does not register the name, so the name may not be available on a subsequent call. Usage _____ .. include:: ../examples/requests/register_name .. _register-name-dispute-api: Register a snap name dispute ---------------------------- If the attempt to register a snap name (with or without ``dry_run``) results in a 409 response with error code ``reserved_name`` or ``already_registered``, the caller can offer the end user to file a snap name dispute, that will be resolved by a human doing snap name dispute reviews. To file a snap name dispute, a request has to be made as follows: .. http:post:: /dev/api/register-name-dispute/ :reqheader Authorization: macaroon authorization header :json string snap_name: the snap name being disputed :status 201: success :status 400: name is available, so a dispute cannot be filed for it :status 401: authentication required :status 403: authorization failed :status 409: name already owned or already disputed by the requesting user :status 503: registration failed .. important:: In order to register a snap name dispute the request's authentication macaroon needs to include the ``package_register`` permission. Refer to the :ref:`macaroon-api` API for information on how to request a macaroon with the right permissions. Usage _____ .. include:: ../examples/requests/register_name_dispute Assert a build for a snap ------------------------- Process and store a snap-build assertion. Currently snap-build is not enforced before publishing an upload. .. http:post:: /dev/api/snaps/(snap_id)/builds :reqheader Authorization: macaroon authorization header :param snap_id: the ``snap_id`` of the snap :json boolean success: whether the build assertion was saved successfully :status 200: success :status 400: error :status 401: authentication required :status 403: authorization failed Usage _____ .. include:: ../examples/requests/snap_build Push a snap build to the Store ------------------------------ .. http:post:: /dev/api/snap-push/ :reqheader Authorization: macaroon based authorization header :json boolean success: true if the request was acknowledged properly :>json string status_url: (deprecated) URL to poll for status changes (for old-style processing) :>json string status_details_url: URL to poll for current server side status changes :status 202: accepted :status 400: error :status 401: authentication required :status 403: authorization failed :status 404: not found .. important:: In order to push a snap the request's authentication macaroon needs to include the ``package_upload`` permission. Refer to the :ref:`macaroon-api` API for information on how to request a macaroon with the right permissions. Usage _____ .. include:: ../examples/requests/push_snap .. _snap-release-api: Release a snap build to a channel --------------------------------- .. http:post:: /dev/api/snap-release/ :reqheader Authorization: macaroon authorization header :`_ :` for further info) :>json boolean success: whether the build was released successfully :>json list channel_map: (optional) a list of all the channels and which versions/revisions are released on each (see below for further info) :>json list opened_channels: (optional) names of the channels that got their first release on the current call :status 200: success :status 400: error :status 401: authentication required :status 403: authorization failed :status 404: not found :status 409: the build or the snap are not ready to release :status 503: release failed .. important:: In order to release a snap the request's authentication macaroon needs to include the ``package_upload`` permission. Refer to the :ref:`macaroon-api` API for information on how to request a macaroon with the right permissions. .. _channel-map: About channel_map _________________ If present, this field will be a list of channel names with more information for each. The list is ordered according to the channel priority hierarchy (e.g.: stable, candidate, beta, edge). Every item in the list is a dict, with at least ``channel`` and ``info`` in it. There are three kind of items. - when the channel doesn't have any release:: {'channel': 'stable', 'info': 'none'} - when the channel has a release:: {'channel': 'candidate', 'info': 'specific', 'version': '2.7', 'revision': 1} - when the channel doesn't have any release, but as a superior channel does, it would use that revision if requested:: {'channel': 'beta', 'info': 'tracking'} .. _progressive-releases: About progressive releases __________________________ If the ``progressive`` field is defined, the release will be done *progressively*, in the sense that a percentage of devices will receive the revision being released. The field ``progressive`` should be a dictionary with the following keys: - ``paused`` a boolean indicating whether the release is active or not. - ``percentage`` a number between 0 and 100, specifies the percentage of devices receiving this release. Releasing a revision with a progressive percentage of 100 and releasing it without a progressive percentage are not equivalent. This behaviour is slightly surprising, but it's a consequence of the fact that not all devices can ever get a progressive revision, since a device may only participate in a progressive release if we have a way to consistently identify it. In order to perform a non-progressive release, either omit including this field, or send the field with all keys with value ``null``. The current status of a progressive release is reported by the :ref:`releases V2 API ` and the :ref:`channel-map V2 API ` endpoints in the ``progressive`` response object, with the following fields: - ``paused`` same as described above. - ``percentage`` same as described above. - ``current-percentage`` a number between 0 and 100, specifying the percentage of devices that have reported **this revision** installed on this channel over the total number of devices that have installed **any revision** on the same channel. This field is only populated in the :ref:`channel-map V2 API ` response. Usage _____ .. include:: ../examples/requests/release_snap Errors ______ .. include:: ../examples/requests/release_snap_errors Obtaining information about a snap ---------------------------------- This API endpoint allows publishers or collaborators to obtain an overview-set of information about their snaps by simply passing its`name`. This endpoint is intended to be an quicker alternative to the current process of resolving `name` to `snap_id` via the :ref:`account-api` response, then hit the **metadata** endpoint for textual fields and the **binary-metadata** for associated icon and screenshots. This endpoint allows clients to get all they need in a single request. .. http:get:: /dev/api/snaps/info/(name) :reqheader Authorization: macaroon authorization header :>json snap_id: unique snap identifier :>json snap_name: name of the snap :>json series: series where this snap is available :>json store: store the snap was registered to :>json publisher: snap publisher reference object, see more details in `About publisher`_ :>json status: whether the snap is currently available in any channel ('published' or 'unpublished') :>json channel_maps_list: map of `{arch: channel_map}` where this snap is currently released, see more details in `About channel_map`_ :>json aliases: remote aliases granted to this snap :>json private: whether this is snap is private or not :>json title: single-line text displayed as title in the snap page :>json summary: single-line summary :>json description: multi-line description :>json keywords: list of proposed keywords to facilitate search :>json license: SPDX 1.1 license expression for this snaps :>json media: list of images associated with this snap, see more details in `About media`_ :>json contact: upstream project contact URL :>json website: upstream project website URL :>json blacklist_countries: list of country codes (ISO ALPHA-2) in which the snap distribution is forbidden :>json whitelist_countries: list of country codes (ISO ALPHA-2) in which the snap is exclusively allowed to be distributed :>json video_urls: list of third-part video URLs associated for this snap :>json public_metrics_enabled: whether public metrics are enabled for this snap or not :>json public_metrics_blacklist: list of public metric names not available for consumption :>json unlisted: whether this snap should be part of search results or not :>json categories: categories list for the snap, (see `Snap categories`_ for more details) :>json update_metadata_on_release: boolean, if set to True, automatically update metadata on subsequent releases to default_track, and stable channel. If set to False (or Null), only update the metadata via website. :>json origin: **DEPRECATED** use ``publisher["username"]`` :>json publisher_name: **DEPRECATED** use ``publisher["display-name"]`` :>json company_name: **DEPRECATED** it is not part of any workflow and will be soon removed. :>json icon_url: **DEPRECATED** use ``media`` :>json screenshot_urls: **DEPRECATED** use ``media`` :status 200: success :status 401: authentication required :status 404: snap not found or not authorized :status 503: internal server error .. important:: In order to fetch snap metrics the request's authentication macaroon needs to include the ``package_access`` permission. See :ref:`macaroon-api` API for information on how to request a macaroon with the right permissions. .. _publisher: About ``publisher`` ___________________ A reference to a snap ``publisher`` is a canonical object across the entire API as:: { "id": "ap8oZPhPCkgEZAGTyU7lRCR0NtNeMyRh", "username": "cprov", "display-name": "Celso Providelo", "validation": "unproven" } The ``id`` property is the user *identifier*, mostly used as a reference in documents exchanged with devices. The ``username`` is the user *unique* store username, normally inherited from the SSO account, it's an ascii-only single-word sequence used to visually disambiguate references to the publisher in the UI. The ``display-name`` is the capitalized, multiple-words and free-form (unicode, emoji, etc) users define as a textual label for themselves. It's normally inherited from the SSO account (First and Last names). The ``validation`` fields represents the identity validation status of the context account in the Store. At the moment, it is either *unproven* or *verified*, where *verified* means the user identity (display-name, username and contact information) is legitimate. For practical purposes, anything other than *unproven* should be considered, at least, as a *verified* identity. .. _media: About ``media`` _______________ The ``media`` field is always an array containing zero or more images associated with a particular snap:: [ {"type": "icon", "width": 256, "height": 256, "url": "https://..."}, {"type": "banner", "width": 720, "height": 240, "url": "https://..."}, {"type": "screenshot", "width": 800, "height": 600, "url": "https://..."}, {"type": "screenshot", "width": 800, "height": 600, "url": "https://..."}, ] The images are referred by ``type`` (icon, banner or screenshot) and ``url`` (store URL serving the corresponding image content). The ``width`` and ``height`` fields may be omitted for some media (eg. media that was uploaded before we started tracking widths and heights, or media types for which we do not measure width and height, such as SVG.) Snap currently can only have a single icon, a single banner and multiple screenshots. Fetch metrics for snaps ----------------------- .. http:post:: /dev/api/snaps/metrics :reqheader Authorization: macaroon authorization header :json list metrics: list of metrics, see :ref:`the-snap-metrics-response` :status 200: success :status 400: error :status 401: authentication required :status 403: authorization failed :status 503: internal server error .. important:: In order to fetch snap metrics the request's authentication macaroon needs to include the ``package_metrics`` permission. See :ref:`macaroon-api` API for information on how to request a macaroon with the right permissions. .. _about-metric-filters: About metric filters ____________________ The metrics endpoint allows clients to POST as many distinct metric ``filters`` as needed to retrieve all required metrics at once:: { "filters": [ {"snap_id": "", "metric_name": "installed_base_by_channel", "start": "2016-12-18", "end": "2017-12-17"} {"snap_id": "", "metric_name": "installed_base_by_country", "start": "2016-12-18", "end": "2017-12-17"} ... ] } Clients can retrieve multiple metrics for any snap they have write access to, with distinct intervals for each metric within a single request. For performance purposes, each individual interval may not be longer than 1 year. The following metrics are available: - **daily_device_change**: contains the 3 series representing the number of "new", "continued" and "lost" devices with the given snap installed compared to the previous day. - **installed_base_by_channel**: contains one series per channel representing the number of devices with the given snap installed, channels with no data across the entire interval are omitted. - **installed_base_by_country**: contains one series per country representing the number of devices with the given snap installed. - **installed_base_by_operating_system**: contains one series per operating_system representing the number of devices with the given snap installed. - **installed_base_by_version**: contains one series per version representing the number of devices withe the given snap installed. - **weekly_device_change**: similar to the 'daily_device_change' metric but operates on a 7 day window. i.e. "new" contains the number of devices that were seen during the last 7 days but not in the previous 7 day and so on for "continued" and "lost". - **weekly_installed_base_by_channel**: similar to the 'installed_base_by_channel' metric but operates in a 7 day window. - **weekly_installed_base_by_country**: similar to the 'installed_base_by_country' metric but operates in a 7 day window. - **weekly_installed_base_by_operating_system**: similar to the 'installed_base_by_operating_system' metric but operates in a 7 day window. - **weekly_installed_base_by_version**: similar to the 'installed_base_by_version' metric but operates in a 7 day window. .. _the-snap-metrics-response: The metrics response ____________________ Each given filter will result in a corresponding ``metrics`` entry in the following format:: { "metrics": [ { "status": "OK|FAIL|NO_DATA", "snap_id": "", "metric_name": "", "buckets": ["", ..., ""], "series": [ { "name":"", "values": [, ..., ] [, "currently_released": true|false] }, ... ] }, ... ] } The ** and ** values are taken from the filters passed to the API in the request. The ``status`` field may be *FAIL* if there are internal problems building this particular metric or *NO_DATA* if there were no samples in the given interval, in both cases the data should be discarded by clients. Otherwise, it is *OK* and the data is good to be used. The ``buckets`` array contains the daily steps for the given [``start``, ``end``] inclusive interval. It does not provide samples more granular than daily. Finally, the ``series`` field contains all available timeseries in the context of the requested metric. The series ``values`` vector (Y axis) is built against the metric ``buckets`` vector (X axis). In ``_by_channel`` series, an extra field ``"currently_released": true|false`` indicates whether the channel referenced by ``name`` is currently open in the snap's channel map. For example, closed channels and nonexistent channels reported by clients are marked as ``"currently_released": false``. Usage _____ .. include:: ../examples/requests/fetch_metrics List all revisions of a snap ---------------------------- .. http:get:: /dev/api/snaps/(snap_id)/history[?arch=&page=1&size=500] :reqheader Authorization: macaroon authorization header :query arch: (optional) when set, retrieve only revisions for this architecture :>jsonarr int revision: the revision of the build :>jsonarr string version: the version of the build :>jsonarr string timestamp: the date and time when the build was uploaded :>jsonarr list series: list of series the build was pushed to :>jsonarr list arch: list of architectures supported by the build :>jsonarr list channels: list of channels the build was released to :>jsonarr list current_channels: list of channels where this revision is currently available :status 200: success :status 400: error :status 401: authentication required :status 404: not found The results can be optionally filtered by architecture via the corresponding query-string parameter `arch`. The results are also paginated, with a default (and maximum) size of 500 entries. Clients can request smaller page sizes and further pages via query-string parameters `size` and `page` (1-indexed). .. important:: There are no particular permissions required in the macaroon for retrieving revision history. Refer to the :ref:`macaroon-api` API for information on how to request a macaroon with the right permissions. .. note:: The user must be the owner or a contributor of the requested package; returns ``404 Not Found`` otherwise. Usage _____ .. include:: ../examples/requests/snap_history Retrieve the publishing state of a snap --------------------------------------- Retrieves the *channel map tree* of a snap for all related tracks and architectures. Includes the default track, if set. .. http:get:: /dev/api/snaps/(snap_id)/state :reqheader Authorization: macaroon authorization header :>json channel_map_tree: a tree where the first layer are the different tracks, the second layer is the series, and the third series are the different architectures for the snap; each leaf of the tree (for the given track/series/architecture combination) is the corresponding channel map (refer to `About channel_map`_ for more info) :>json default_track: the default track set for the context snap, included only if there is a default track for it. :query architecture: (optional) when set, filter results for this architecture only :status 200: success :status 400: error :status 401: authentication required :status 404: not found .. important:: The request's authentication macaroon needs to include the ``package_access`` permission. See :ref:`macaroon-api` API for information on how to request a macaroon with the right permissions. The user must be the owner or a contributor of the requested package. Usage _____ .. include:: ../examples/requests/snap_state Retrieve the publishing status of a snap ---------------------------------------- [DEPRECATED] Please refer to the `/state` documentation above. Retrieves the `channel map` of a snap for all related architectures. .. http:get:: /dev/api/snaps/(snap_id)/status :reqheader Authorization: macaroon authorization header :>json object: map of `{arch: channel_map}` for each architecture related to the context snap: refer to `About channel_map`_ :query arch: (optional) when set, retrieve the channel map for this architecture only :status 200: success :status 400: error :status 401: authentication required :status 404: not found .. important:: There are no particular permissions required in the macaroon for retrieving the snap status. Refer to the :ref:`macaroon-api` API for information on how to request a macaroon with the right permissions. .. note:: The user must be the owner or a contributor of the requested package. Usage _____ .. include:: ../examples/requests/snap_status Managing snap metadata ---------------------- The `metadata` endpoint allows clients to fetch and update textual attributes of a snap. .. http:get:: /dev/api/snaps/(snap_id)/metadata :reqheader Authorization: macaroon authorization header :>json blacklist_countries: list of country codes (ISO ALPHA-2) in which the snap distribution is forbidden :>json categories: categories information for the snap, (see `Snap categories`_ for more details) :>json contact: upstream project contact URL :>json description: multi-line description :>json default_track: the default track set for the snap (`null` if none is set) :>json keywords: list of proposed keywords to facilitate search :>json license: SPDX 1.1 license expression for this snaps :>json private: whether this is snap is private or not :>json public_metrics_blacklist: list of public metric names not available for consumption :>json public_metrics_enabled: whether public metrics are enabled for this snap or not :>json summary: single-line summary :>json title: single-line text displayed as title in the snap page :>json unlisted: whether this snap should be part of search results or not :>json website: upstream project website URL :>json whitelist_countries: list of country codes (ISO ALPHA-2) in which the snap is exclusively allowed to be distributed :>json update_metadata_on_release: boolean, if set to True, automatically update metadata on subsequent releases to default_track, and stable channel. If set to False (or Null), only update the metadata via website. :status 200: success :status 401: authentication required :status 404: not found or not allowed POST-ing to `metadata` allows clients to update attributes after checking for conflicts. .. http:post:: /dev/api/snaps/(snap_id)/metadata[?conflict_on_update=false] :reqheader Authorization: macaroon authorization header :jsonarr type: whether it's an `icon`, `screenshot` or `banner` :>jsonarr filename: the original filename :>jsonarr url: the url where the file is served :>jsonarr hash: the SHA-256 hex-digest of the file :status 200: success :status 401: authentication required :status 404: not found or not allowed POST-ing to `binary-metadata` involves a specially-crafted `multipart` payload, where the `info` part is a JSON-encoded array of objects describing the subsequent parts, as in:: { "info": [ {"key": "the_icon", "type": "icon", "filename": "my_icon.png", "hash": ""}, {"key": "ss_1", "type": "screenshot", "filename": "ss_1.png", "hash": ""}, {"key": "ss_2", "type": "screenshot", "filename": "ss_2.png", "hash": ""}, ] } Similarly to the textual endpoint, POST-ing to `binary-metadata` will submit the proposed files to a conflict check against files uploaded via webui (based on the "hash" attribute in `info`) before updating the snap information. It is an additive operation, i.e. existing icon or screenshots will not get removed as long as they are still referenced in the `info` structure. .. http:post:: /dev/api/snaps/(snap_id)/binary-metadata[?conflict_on_update=false] :reqheader Authorization: macaroon authorization header :form info: JSON-encoded array of objects describing the next parts :form : binary metadata as described in `info` (form-encoded) :form <...>: additional files :status 200: success :status 400: malformed payload :status 401: authentication required :status 404: snap not found or not allowed :status 409: one or more files conflicts with existing data, binary-metadata not updated :status 415: unsupported media type :status 422: invalid resolution, invalid aspect ratio, too many items or file size too big PUT-ing to `binary-metadata` will first **remove** all files related to the snap not mentioned in the `info` structure and then add the proposed ones. .. http:put:: /dev/api/snaps/(snap_id)/binary-metadata[?conflict_on_update=false] :reqheader Authorization: macaroon authorization header :form info: JSON-encoded array of objects describing the next parts :form : binary metadata as described in `info` (form-encoded) :form <...>: additional files :status 200: success :status 400: malformed payload :status 401: authentication required :status 404: snap not found or not allowed :status 415: unsupported media type :status 422: invalid resolution, invalid aspect ratio, too many items or file size too big .. important:: In order to fetch or update snap metadata the request's authentication macaroon needs to include the ``package_upload`` permission. See :ref:`macaroon-api` API for information on how to request a macaroon with the right permissions. Usage _____ .. include:: ../examples/requests/snap_metadata Snap categories _______________ The metadata ``categories`` field is a dict containing the following: - ``locked``: whether categories are locked from modification by snap publishers - ``items``: a list of dicts having: - ``name``: the name of the category - ``since``: an ISO 8601 timestamp of when this category was assigned - ``featured``: whether this category is set by store curators .. include:: ../examples/requests/snap_categories Supervise the status of a build -------------------------------- The response from a successful hit to the Push endpoint includes a ``status_details_url`` (see `Push a snap build to the Store`_ for more details). The ``status_details_url`` will return proper information about the processing of the build happening server side. .. http:get:: /dev/api/snaps/(snap_id)/builds/(updown_id)/status :>json boolean processed: true if the server side processing already finished (if false, please wait a few seconds and hit the ``status_details_url`` again). :>json boolean can_release: true if all finished OK server side, so the client can proceed to release (see `Release a snap build to a channel`_ for more info). :>json string code: a short (but representative) string indicating concisely in which stage the server side processing is (see below for the list) :>json string url: (optional) present if the user can continue the procedure, realize some action and/or retrieve some information through the web site. :>json list errors: (optional) present only if the build processing ended in an error state, this list of error messages will help the user to fix the build (see below for format). :>json int revision: (optional) the revision of the pushed build, present only if the build binary structure was OK and a revision was assigned to it. :status 200: success :status 404: not found The ``code`` informing in which stage the processing is can be any of the following: - ``being_processed``: the processing still didn't finish - ``processing_error``: there was an error processing the build - ``need_manual_review``: a manual review is needed for the push to be approved - ``ready_to_release``: free to go The ``errors`` field (if present) will be a list of dictionaries, each dict containing... - a ``code`` element, which is a short string to indicate unambiguously the type of error, and can be used by the client to present a special message or take an specific action; note that it also can be ``null`` if the error type is generic. - a ``message`` element, which is a short descriptive message for the error. Close a channel for a snap package ---------------------------------- .. http:post:: /dev/api/snaps/(snap_id)/close :reqheader Authorization: macaroon authorization header :json object channel_maps: channel_map for each architecture related to the context snap. :>json list closed_channels: list of channels currently closed for the context snap. :status 200: success :status 400: error :status 401: authentication required :status 403: authorization failed :status 404: not found .. important:: In order to close a channel the request's authentication macaroon needs to include the ``package_upload`` permission. Refer to the :ref:`macaroon-api` API for information on how to request a macaroon with the right permissions. .. _errors: Errors ====== The *Snaps API* uses conventional HTTP response codes to indicate success or failure of an API request. In general, codes in the 2xx range indicate success, codes in the 4xx range indicate an error that resulted from the provided information (e.g. a required parameter was missing) and codes in the 5xx range indicate an error with our servers. Here is detailed the format for API responses that end in error. This applies to all the 4xx responses, but also to some 5xx ones (if possible, the client should be prepared to handle 5xx responses with no informational body). Note that this structure format does not apply to 2xx and 3xx responses, as those are note errors. .. important:: Not all API endpoints are migrated yet to this new error format Format ------ An error response body will contain the following field: - ``error_list``: a list of one or several items (never empty), each item described by... - ``message``: a text in English describing the error that happened, ready to show to the user. - ``code``: a short (but representative) string indicating concisely the error; it's aimed for clients to take specific actions and react to the problem. See below for the list of existing codes. Additionally and for backwards compatibility reasons, some other fields may be present as well, but are considered deprecated and will be removed in the near future. No status or success indication is returned inside the response body, the client should react properly to the received HTTP return code according to its `well established semantics `_. Codes ----- These are the codes used in the response and their meanings: - ``already_claimed``: the requested snap name is already claimed. - ``already_owned``: the user already owns the requested snap name. - ``already_registered``: the requested snap name is already registered by someone else. - ``assertion-creation-failed``: the assertion associated with the requested action could not be created. - ``bad-request``: there is a problem in the structure of the request. - ``internal-server-error``: some unexpected problem server side; this will be the code in all 5xx cases. - ``failed-to-register``: the snap name registration failed because the snap-declaration assertion couldn't be created. - ``invalid``: the snap name is not valid: it should only have ASCII lowercase letters, numbers, and hyphens, and must have at least one letter; furthermore, it should not start nor end with a hyphen, it should not have two hyphens in a row, and it should have no more than 40 characters in total. - ``invalid_choice``: current selected choice is not one of the available choices. - ``invalid-field``: the field received in the request has format problems (e.g.: must be a number and it's not) or value problems (e.g.: it specified a channel "foo" but that is an invalid channel for this Store). - ``macaroon-permission-required``: the macaroon authorization is missing in the received request or not enough for it to be fulfilled. - ``media-file-size-too-big``: the uploaded media is too big. - ``media-invalid-aspect-ratio``: the uploaded media has an invalid aspect ratio. - ``media-invalid-resolution``: the uploaded media has an invalid resolution. - ``media-modified``: the media item was unexpectedly modified during validation. This should never occur. - ``media-too-many-items``: the uploaded media type has too many items, please remove or update an existing. - ``media-unsupported-type``: the uploaded media is in a format that is not supported. - ``missing-field``: the request received must include a field which was not present. - ``name-not-available-for-dispute``: the given snap name cannot be disputed because is already available. - ``name-not-registered``: the given snap name needs to be registered before an upload attempt is made. - ``register_window``: the user has reached their quota for registering names, they cannot register any more snap names temporarily. - ``required``: the field in the request can't be empty or null. - ``reserved_name``: the requested snap name is reserved, a snap name dispute must be filed to get access to the name. - ``resource-forbidden``: the resources in question cannot be accessed by the request authorization. - ``resource-not-found``: one or more fields are included to specify a resource, but it is not found in the Store. - ``resource-not-ready``: the request actions on a resource that is not ready yet for that purpose; normally something else would need to be done first on the resource before this request can be repeated. - ``revoked_name``: the requested snap name was already owned by the user but is currently revoked. - ``user-not-ready``: the user is not ready to issue the received request; normally some actions would need to be done in the user account before repeating the request. Examples -------- A simple error: .. sourcecode:: json { "error_list": [{ "message": "The field 'expiration' must be an integer", "code": "invalid-field" }] } A multiple error: .. sourcecode:: json { "error_list": [{ "message": "The 'foo' field is required", "code": "missing-field" }, { "message": "The 'bar' field is required", "code": "missing-field" }, { "message": "The 'baz' field must not be empty", "code": "invalid-field" }] }