Contents
The Snap Packages API provides a series of endpoints supporting common actions during the lifetime of a snap package.
The Snap Packages API is exposed at the following base URLs:
JSON will be returned in all responses from the API, including errors.
POST /dev/api/register-name/¶| Request Headers: | |
|---|---|
|
|
| Query Parameters: | |
|
|
| Request JSON Object: | |
|
|
| Response JSON Object: | |
|
|
| Status Codes: |
|
Important
In order to register a snap name the request’s authentication macaroon needs to include
the package_upload permission. Refer to the Macaroon 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 via the web ui.
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 later.
Before pushing a snap package, the developer needs to register the package name.
Request:
POST /dev/api/register-name/ HTTP/1.1
Host: myapps.developer.ubuntu.com
Authorization: Macaroon root=..., discharge=...
Content-Type: application/json
{
"snap_name": "foo"
}
Response:
HTTP/1.1 201 CREATED
Content-Type: application/json
{
"snap_id": "some-snap-id"
}
The developer can state whether the package is going to be marked as private on
first upload by setting the is_private field to true.
Request:
POST /dev/api/register-name/ HTTP/1.1
Host: myapps.developer.ubuntu.com
Authorization: Macaroon root=..., discharge=...
Content-Type: application/json
{
"is_private": true,
"snap_name": "foo"
}
Response:
HTTP/1.1 201 CREATED
Content-Type: application/json
{
"snap_id": "some-snap-id"
}
It’s possible to just trigger validation for a name without actually registering
it by setting dry_run as a query parameter.
Request:
POST /dev/api/register-name/?dry_run=1 HTTP/1.1
Host: myapps.developer.ubuntu.com
Authorization: Macaroon root=..., discharge=...
Content-Type: application/json
{
"snap_name": "foo"
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"snap_id": null
}
If the macaroon used for authentication does not contain the package_upload permission
an error response will be returned.
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: application/json
{
"type": "devportal:v1:macaroon-permission-required",
"title": "Macaroon missing required permission.",
"detail": "Permission is required: package_upload",
"status": 403,
"permission": "package_upload",
"error_list": [{
"message": "Permission is required: package_upload",
"code": "macaroon-permission-required"
}]
}
The developer needs to sign the Developer Programme Agreement before pushing snap packages. Failing to do so will result in an error response
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: application/json
{
"error_list": [
{
"message": "Developer has not signed agreement.",
"code": "user-not-ready",
"extra": {
"url": "https://myapps.developer.ubuntu.com/dev/agreements/new/",
"api": "https://myapps.developer.ubuntu.com/dev/api/agreement/"
}
}
],
"errors": "Developer has not signed agreement.",
"success": false
}
The developer must have a short namespace before pushing snap packages. Failing to do so will result in an error response
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: application/json
{
"error_list": [
{
"message": "Developer profile is missing short namespace.",
"code": "user-not-ready",
"extra": {
"url": "http://sca-trusty.local:8000/dev/account/"
}
}
],
"errors": "Developer profile is missing short namespace.",
"success": false
}
In the event that the request contained invalid data, an error response will be
returned detailing the problem(s). Each of them containing at least a code,
a human readable reason and the name of the field that’s causing the
error. Here’s an example response for errors triggered in the snap_name.
Response:
HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
{
"type": "devportal:v1:request-invalid",
"title": "Invalid request.",
"detail": "Submitted data is not valid.",
"status": 400,
"invalid_params": [{
"code": "invalid",
"name": "snap_name",
"reason": "The package name 'some name' is not valid. It can only contain lowercase ascii letters, numbers and hyphens."
}],
"error_list": [{
"message": "The package name 'some name' is not valid. It can only contain lowercase ascii letters, numbers and hyphens.",
"code": "invalid",
"extra": {"name": "snap_name"}
}]
}
In the event that the requested name is already registered by another
publisher, the error response will contain extra metadata such as the
suggested_snap_name and register_name_url.
Response:
HTTP/1.1 409 CONFLICT
Content-Type: application/json
{
"type": "devportal:v1:name-already-registered",
"title": "Name already registered.",
"detail": "'some-name' is already registered.",
"status": 409,
"code": "already_registered",
"register_name_url": "https://myapps.developer.ubuntu.com/dev/click-apps/register-name/",
"suggested_snap_name": "namespace-some-name",
"error_list": [{
"message": "'some-name' is already registered.",
"code": "already_registered"
}]
}
Unless it’s an already claimed name which is waiting for review, in which case the response would be:
Response:
HTTP/1.1 409 CONFLICT
Content-Type: application/json
{
"type": "devportal:v1:name-already-registered",
"title": "Name already registered.",
"detail": "You already registered a claim for 'some-name'.",
"status": 409,
"code": "already_claimed",
"error_list": [{
"message": "You already registered a claim for 'some-name'.",
"code": "already_claimed"
}]
}
Or it’s an already owned name, in which case the response would be:
Response:
HTTP/1.1 409 CONFLICT
Content-Type: application/json
{
"type": "devportal:v1:name-already-registered",
"title": "Name already registered.",
"detail": "You already own 'some-name'.",
"status": 409,
"code": "already_owned",
"error_list": [{
"message": "You already own 'some-name'.",
"code": "already_owned"
}]
}
In the event that the requested name is a reserved name, the error response
will contain extra metadata such as the suggested_snap_name and
register_name_url.
Response:
HTTP/1.1 409 CONFLICT
Content-Type: application/json
{
"type": "devportal:v1:name-reserved",
"title": "Name is reserved.",
"detail": "'some-name' is a reserved name.",
"status": 409,
"code": "reserved_name",
"register_name_url": "https://myapps.developer.ubuntu.com/dev/click-apps/register-name/",
"suggested_snap_name": "namespace-some-name",
"error_list": [{
"message": "'some-name' is a reserved name.",
"code": "reserved_name"
}]
}
If names are tried to be registered too quickly, the following error would be
returned with the retry_after field (also reflected in the Retry-After
response header) containing the amount of time to wait in seconds before the
next attempt:
Response:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 59
{
"status": 429,
"code": "register_window",
"title": "You must wait before next name registration.",
"detail": "You can register up to 10 names every 10\u00a0minutes. You must wait 7\u00a0minutes before the next snap-name registration.",
"type": "devportal:v1:name-window-wait",
"retry_after": 399,
"error_list": [{
"message": "You can register up to 10 names every 10\u00a0minutes. You must wait 7\u00a0minutes before the next snap-name registration.",
"code": "register_window"
}]
}
In some cases the submitted data is valid, but the request might fail to complete. In such cases a response like the following will be returned
Response:
HTTP/1.1 503 SERVICE UNAVAILABLE
Content-Type: application/json
{
"status": 503,
"code": "failed-to-register",
"title": "Invalid request.",
"detail": "Failed to register",
"error_list": [
{
"message": "Failed to register",
"code": "failed-to-register"
}
],
"type": "devportal:v1:request-invalid"
}
Process and store a snap-build assertion. Currently snap-build is not enforced before publishing an upload.
POST /dev/api/snaps/(snap_id)/builds¶| Request Headers: | |
|---|---|
|
|
| Parameters: |
|
| Request JSON Object: | |
|
|
| Response JSON Object: | |
|
|
| Status Codes: |
|
To submit a build assertion of their package, a developer posts a request like the following:
Request:
POST /dev/api/snaps/some_snap_id/builds HTTP/1.1
Host: myapps.developer.ubuntu.com
Authorization: Macaroon root=..., discharge=...
Content-Type: application/json
{
"assertion": "utf-8 signed assertion blob"
}
Note
The assertion blob is simply the snap-build assert data as assembled and signed by developers.
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"headers": {
"authority-id": "",
"grade": "",
"sign-key-sha3-384": "",
"snap-id": "",
"snap-sha3-384": "",
"snap-size": "",
"timestamp": "",
"revision": "",
"type": "snap-build"
}
}
If the macaroon used for authentication does not contain the package_upload
permission or is restricted to a set of snap packages that doesn’t include
this package, an error response will be returned
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: application/problem+json
{
"type": "devportal:v1:macaroon-permission-required",
"title": "Macaroon missing required permission.",
"detail": "Permission is required: package_upload",
"status": 403,
"permission": "package_upload"
}
The developer needs to sign the Developer Programme Agreement before they can assert builds. Failing to do so will result in an error response
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: text/plain
Developer has not signed agreement.
The developer needs to have defined their namespace in their user profile before they can assert builds. Failing to do so will result in an error response
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: text/plain
Developer profile is missing short namespace.
In the event that the request is missing fields, an error response will be returned detailing the problem
Response:
HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
{
"success": false,
"errors": [{"name": ["This field is required."]}]
}
If the content of assertion has any invalid information, an error response will be returned
Response:
HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
{
"success": false,
"errors": [{"name": ["Not a valid snap-build assertion."]}]
}
POST /dev/api/snap-push/¶| Request Headers: | |
|---|---|
|
|
| Request JSON Object: | |
|
|
| Response JSON Object: | |
|
|
| Status Codes: |
|
Important
In order to push a snap the request’s authentication macaroon needs to include
the package_upload permission. Refer to the Macaroon API for information on
how to request a macaroon with the right permissions.
To submit a new version of their snap package, a developer pushes it to the Store
Request:
POST /dev/api/snap-push/ HTTP/1.1
Host: myapps.developer.ubuntu.com
Content-Type: application/json
{
"name": "foo",
"updown_id": "some-updown-id"
}
Response:
HTTP/1.1 202 ACCEPTED
Content-Type: application/json; charset=utf-8
{
"success": true,
"status_url": "https://myapps.developer.ubuntu.com/dev/click-apps/42"
}
Note
Receiving a 202 response means the Store has acknowledged the submission and will proceed to analyze the snap package for errors before it’s fully accepted.
If the macaroon used for authentication does not contain the package_upload
permission or is restricted to a set of snap packages that doesn’t include
this package, an error response will be returned
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: application/problem+json
{
"type": "devportal:v1:macaroon-permission-required",
"title": "Macaroon missing required permission.",
"detail": "Permission is required: package_upload",
"status": 403,
"permission": "package_upload"
}
If a push is attempted for a package that has not had its name registered beforehand, an error like this will be returned
Response:
HTTP/1.1 404 NOT FOUND
The developer needs to sign the Developer Programme Agreement before they can push snap packages. Failing to do so will result in an error response
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: text/plain
Developer has not signed agreement.
The developer needs to have defined their namespace in their user profile before they can push snap packages. Failing to do so will result in an error response
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: text/plain
Developer profile is missing short namespace.
In the event that the request contained invalid data, an error response will be returned detailing the problem
Response:
HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
{
"success": false,
"errors": [{"name": ["This field is required."]}]
}
POST /dev/api/snap-release/¶| Request Headers: | |
|---|---|
|
|
| Request JSON Object: | |
|
|
| Response JSON Object: | |
|
|
| Status Codes: |
|
Important
In order to release a snap the request’s authentication macaroon needs to include
the package_upload permission. Refer to the Macaroon API for information on
how to request a macaroon with the right permissions.
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'}
When a developer is ready to make their snap package available to the world, they can release it like
Request:
POST /dev/api/snap-release/ HTTP/1.1
Host: myapps.developer.ubuntu.com
Content-Type: application/json
{
"name": "foo",
"revision": "1",
"channels": ["stable"]
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"success": true
"channel_map": [
{'info': 'none', 'channel': 'stable'},
{'info': 'specific', 'version': '2.7', 'channel': 'candidate', 'revision': 1},
{'info': 'tracking', 'channel': 'beta'},
{'info': 'tracking', 'channel': 'edge'}
],
"opened_channels": ["candidate"],
}
If the macaroon used for authentication does not contain the package_upload
permission or is restricted to a set of snap packages that doesn’t include
this package, an error response will be returned
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: application/problem+json
{
"type": "devportal:v1:macaroon-permission-required",
"title": "Macaroon missing required permission.",
"detail": "Permission is required: package_upload",
"status": 403,
"permission": "package_upload"
}
If a release is requested for a package that has not had its name registered beforehand, an error like this will be returned
Response:
HTTP/1.1 404 NOT FOUND
The developer needs to sign the Developer Programme Agreement before they can release snap packages. Failing to do so will result in an error response
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: text/plain
Developer has not signed agreement.
The developer needs to have defined their namespace in their user profile before they can release snap packages. Failing to do so will result in an error response
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: text/plain
Developer profile is missing short namespace.
In the event that the request contained invalid data, an error response will be returned detailing the problem
Response:
HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
{
"success": false,
"errors": [
{"name": ["This field is required."]}
]
}
In some cases the submitted data is valid, but the request might fail to complete. In such cases a response like the following will be returned
Response:
HTTP/1.1 503 SERVICE UNAVAILABLE
Content-Type: application/json
"Failed to publish"
POST /dev/api/snaps/metrics¶| Request Headers: | |
|---|---|
|
|
| Request JSON Object: | |
|
|
| Response JSON Object: | |
|
|
| Status Codes: |
|
Important
In order to fetch snap metrics the request’s authentication macaroon needs to include
the package_upload permission. See Macaroon API for information on how to
request a macaroon with the right permissions.
The metrics endpoint allows clients to POST as many distinct metric filters needed to retrieve all required metricts at once:
[
{"snap_id": "<SNAP-ID>", "metric_name": "installed_base_by_channel",
"start": "2016-12-18", "end": "2017-12-17"}
{"snap_id": "<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:
Each given filter will result in a corresponding metrics entry in the following format:
{
"status": "OK|FAIL|NO_DATA",
"snap_id": "<SNAP-ID>",
"metric_name": "<METRIC_NAME>",
"buckets": ["<DAY-1>", ..., "<DAY-N>"],
"series": [
{"name":"<SERIES_NAME>",
"values": [<SAMPLE-1>, ..., <SAMPLE-N>]},
...
]
}
The <SNAP_ID> and <METRIC_NAME> values are taken from the filters passed to the API in the request.
The status field may be FAIL if there are internal problem 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).
Any publisher or collaborator can fetch metrics from their snaps.
First step would be to build a macaroon authorization, please follow the
instructions in Macaroon API and make sure it contains package_upload
permission
The snap_ids can be obtained via the publisher WebUI or via the Account API.
Request:
POST /dev/api/snaps/metrics HTTP/1.1
Host: dashboard.snapcraft.io
Authorization: ...
Content-Type: application/json
{
"filters": [
{"snap_id": "wKFeK2U7Y2CB53vRJwg9MeR9bqfPvtZK",
"metric_name": "installed_base_by_channel",
"start": "2017-12-16", "end": "2017-12-17"}
]
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"metrics": [
{
"status": "OK",
"snap_id": "wKFeK2U7Y2CB53vRJwg9MeR9bqfPvtZK",
"metric_name": "installed_base_by_channel",
"buckets": ["2017-12-16"],
"series": [
{"values": [124], "name":"stable"},
{"values": [270], "name":"beta"},
{"values": [74], "name":"candidate"},
{"values": [147], "name":"edge"}
]
}
]
}
If the macaroon used for authentication does not contain the package_upload
permission or is restricted to a set of snap packages that doesn’t include
this package, an error response will be returned
Response:
HTTP/1.1 403 FORBIDDEN
Content-Type: application/problem+json
{
"error_list": [
{
"message": "Not authorized to access the following snap_ids: <SNAP-ID>",
"code": "macaroon-permission-required"
}
],
}
In the event that the request contained invalid filters, an error response will be returned detailing the problem
Response:
HTTP/1.1 400 BAD REQUEST
Content-Type: application/json
{
"error_list": [
{
"message": "Filter missing required keys at index 0: end",
"code": "invalid"
}
],
}
GET /dev/api/snaps/(snap_id)/history¶| Request Headers: | |
|---|---|
|
|
| Query Parameters: | |
|
|
| Response JSON Array of Objects: | |
|
|
| Status Codes: |
|
Important
There are no particular permissions required in the macaroon for retrieving revision history. Refer to the Macaroon 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.
List all revisions of the snap with id some_snap_id in the current default series:
Request:
GET /dev/api/snaps/some_snap_id/history HTTP/1.1
Host: myapps.developer.ubuntu.com
Authorization: Macaroon root=..., discharge=...
Content-Type: application/json
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
[
{
"series": [
"16"
],
"channels": [
"beta"
],
"version": "1.1-amd64",
"timestamp": "2016-10-05T00:33:58.209",
"current_channels": [
"beta",
"edge"
],
"arch": "amd64",
"revision": 4
},
{
"series": [
"16"
],
"channels": [
"edge"
],
"version": "1.0-i386",
"timestamp": "2016-10-03T20:33:58.162",
"current_channels": [
"edge"
],
"arch": "i386",
"revision": 3
},
{
"series": [
"16"
],
"channels": [
"stable",
],
"version": "1.0-amd64",
"timestamp": "2016-10-01T10:33:58.021",
"current_channels": [
"stable",
"candidate"
],
"arch": "amd64",
"revision": 2
}
]
Filter revisions by series and architecture:
Request:
GET /dev/api/snaps/some_snap_id/history?series=16&arch=i386 HTTP/1.1
Host: myapps.developer.ubuntu.com
Authorization: Macaroon root=..., discharge=...
Content-Type: application/json
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
[
{
"series": [
"16"
],
"channels": [
"edge"
],
"version": "1.0-i386",
"timestamp": "2016-10-03T20:33:58.162",
"current_channels": [
"edge"
],
"arch": "i386",
"revision": 3
}
]
Retrieves the channel map of a snap for all related architectures.
GET /dev/api/snaps/(snap_id)/status¶| Request Headers: | |
|---|---|
|
|
| Response JSON Object: | |
|
|
| Query Parameters: | |
|
|
| Status Codes: |
|
Important
There are no particular permissions required in the macaroon for retrieving the snap status. Refer to the Macaroon 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.
Retrieve the channel map for all architectures of the snap with id some_snap_id in the current default series:
Request:
GET /dev/api/snaps/some_snap_id/status HTTP/1.1
Host: myapps.developer.ubuntu.com
Authorization: Macaroon root=..., discharge=...
Content-Type: application/json
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"i386": [
{
"info": "none",
"channel": "stable"
},
{
"info": "none",
"channel": "candidate"
},
{
"info": "none",
"channel": "beta"
},
{
"info": "specific",
"version": "1.0-i386",
"channel": "edge",
"revision": 3
}
],
"amd64": [
{
"info": "specific",
"version": "1.0-amd64",
"channel": "stable",
"revision": 2
},
{
"info": "tracking",
"channel": "candidate"
},
{
"info": "specific",
"version": "1.1-amd64",
"channel": "beta",
"revision": 4
},
{
"info": "tracking",
"channel": "edge"
}
]
}
Filter by series and architecture:
Request:
GET /dev/api/snaps/some_snap_id/status?series=16&arch=amd64 HTTP/1.1
Host: myapps.developer.ubuntu.com
Authorization: Macaroon root=..., discharge=...
Content-Type: application/json
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"amd64": [
{
"info": "specific",
"version": "1.0-amd64",
"channel": "stable",
"revision": 2
},
{
"info": "tracking",
"channel": "candidate"
},
{
"info": "specific",
"version": "1.1-amd64",
"channel": "beta",
"revision": 4
},
{
"info": "tracking",
"channel": "edge"
}
]
}
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.
GET /dev/api/snaps/(snap_id)/builds/(updown_id)/status¶| Response JSON Object: | |
|---|---|
|
|
| Status Codes: |
|
The code informing in which stage the processing is can be any of the following:
being_processed: the processing still didn’t finishprocessing_error: there was an error processing the buildneed_manual_review: a manual review is needed for the push to be approvedready_to_release: free to goThe errors field (if present) will be a list of dictionaries, each dict containing…
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.message element, which is a short descriptive message for the error.POST /dev/api/snaps/(snap_id)/close¶| Request Headers: | |
|---|---|
|
|
| Request JSON Object: | |
|
|
| Response JSON Object: | |
|
|
| Status Codes: |
|
Important
In order to close a channel the request’s authentication macaroon needs to include
the package_upload permission. Refer to the Macaroon API for information on
how to request a macaroon with the right permissions.
GET /dev/api/snaps/(snap_id)/developers¶| Request Headers: | |
|---|---|
|
|
| Parameters: |
|
| Response JSON Object: | |
|
|
| Status Codes: |
|
PUT /dev/api/snaps/(snap_id)/developers¶| Request Headers: | |
|---|---|
|
|
| Parameters: |
|
| Request JSON Object: | |
|
|
| Response JSON Object: | |
|
|
| Status Codes: |
|
Important
In order to manage collaborators the request’s authentication macaroon needs to include
the package_manage permission. Refer to the Macaroon API for information on
how to request a macaroon with the right permissions.
Note
The assertion’s publisher-id must be the authorized user’s account ID.
The assertion’s authority-id must be the same as the publisher-id,
i.e. the assertion must be signed by one of the authorized user’s private
keys.
The snap ID and any developer account ID in the assertion must identify a valid snap and developer respectively.
The Snap Packages 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
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 stablished semantics.
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.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 we failed to
store the assertion.invalid: the snap name is not valid. It can only contain lowercase
ascii letters, numbers and hyphens.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.missing-field: the request received must include a field which was
not present.register_window: the user cannot register more snap names temporarily.required: the field in the request can’t be empty or null.reserved_name: the requested snap name is reserved.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.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.A simple error:
{
"error_list": [{
"message": "The field 'expiration' must be an integer",
"code": "invalid-field"
}]
}
A multiple error:
{
"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"
}]
}