General considerations

  • SSL only
  • JSON
  • UTF-8

Rate limiting

All API requests are rate limited. Upon reaching this limit, a HTTP response with status code 429 is returned. The body of such responses will be like:

 "message": "Too many requests. Please try again later.",
 "extra": {"Retry-After": 53}

Standard response format


HTTP/1.1 200 OK
Content-Type: application/json

  "href": "https://login.ubuntu.com/api/v2/accounts/openid123",
  "openid": "openid123",
  "email": "foo@example.com",
  "displayname": "Foo Bar Baz",
  "status": "NEW",
  "verified": true,
  "emails": [
      "href": "https://login.ubuntu.com/api/v2/emails/foo@example.com"


Content-Type: application/json

  "code": "INVALID_DATA",
  "message": "Invalid request data.",
  "extra": {
    "displayname": "Field required"

Standard errors

The following generic error codes are currently defined:

  • INVALID_DATA: Input data failed to validate.

    Error status code 400.

    The extra field includes the names of the fields that failed to validate, and a reason why they failed.

See the relevant documentation for errors specific to each api.

New format Errors

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.


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:

  • account-not-ready: the account is deactivated, suspended or account email is not validated.
  • bad-request: there is a problem in the structure of the request.
  • field-required: the field in the request can’t be empty or null.
  • internal-server-error: some unexpected problem server side; this will be the code in all 5xx cases.
  • invalid-credentials: the credentials for the authentication are not valid (e.g.: the username or password is not correct).
  • invalid-data: the data is incorrect or corrupt.
  • permission-required: the macaroon authorization is missing in the received request or not enough for it to be fulfilled.
  • 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.
  • twofactor-required: two-factor authentication is required for this request but was not provided.
  • 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"