Two endpoints are defined: /index/static
and /index/dynamic
.
They take the same query parameters and return the same results (except possibly for HTTP headers),
but the difference encodes a hint as to the intent of the client.
/index/static
: Requests to this endpoint are expected to be repeated with exactly
the same parameters,
possibly by many different clients. It is useful for caches to cache the data.
/index/dynamic
: Requests to this endpoint are constructed via user interaction
and are expected to be rarely repeated.
The server MAY choose to set headers such as Cache-Control: no-store
on the response,
but it may also use to the hint to influence internal caching,
or may entirely ignore the hint.
The following query parameters are understood:
repository=<value>
: limit results to images in the given repositorytag=<value>
: limit results to images with a given tag, and images within image lists with the given tagos=<value>
: limit results to images for the given operating system. Values are as forGOOS
. [Note 1]architecture=<value>
: limit results to images for the given architecture. Values are as forGOARCH
. [Note 1]annotation:<annotation>=<value>
,annotation:<annotation>:exists=1
: Limit results to images where the annotation<annotation>
has the given value, or for the:exists
form, exists with any value.label:<label>=<value>
,label:<label>:exists=1
: Limit results to images where the label<label>
has the given value, or for the:exists
form, exists with any value.
For parameters with :exists
suffix,
it is undefined what happens if any value other than 1
is specified.
Multiple parameters with the same key are OR'ed together: An image I matches a given set of query parameters S iff: For each K=V in S: either K=V matches S or there is another K=V′ in S with the same K and K=V′ matches S.
Example: label:org.example.a:exists=1&label:org.example.b=X&label:org.example.b=Y
matches images which have any org.example.a
label,
and an org.example.b
label with the value X
or Y
.
For requests to /static
,
Clients SHOULD sort their request parameters by the URL-encoded value of the <key>=<value>
string.
Python example:
params = [
('label', 'latest'),
('annotation:org.flatpak.metadata:exists', '1'),
('architecture': 'amd64')
]
quoted = [ urllib.quote_plus(k) + '=' + urllib.quote_plus(v) for k, v in params ]
url = index_server + '/index/static?' + '&'.join(sorted(quoted))
The basic structure of the JSON returned from a request is:
{
"Registry": "<url>",
"Results": [Repository, ...]
}
Registry
: URL to the registry where the images are found. This is interpreted with the base URL being the URL of the document (that is/index/[static/dynamic]
.)Results
: matching images, grouped by repository
{
"Name": "some/repository",
"Images": [Image, ...]
"Lists": [ImageList, ...]
}
Name
: name of the repository containing the given image and image lists. (An image list is a Docker Manifest List or an OCI Image Index.)Images
: images directly tagged in this repository that matchedImage Lists
: images within image lists that matched, grouped by image list.
{
"Tags": ["<tag>", ...],
"Digest": "<digest>",
"MediaType": "<media type>",
"OS": "<os>",
"Architecture": "<architecture>",
"Annotations": {
"org.example.annotations.x": "<value>",
...
}
"Labels": {
"com.redhat.component": "<value>",
...
}
}
Tags
: List of tags applied to the image. [Note 2]Digest
: The digest of the image manifest. The manifest can be retrieved be retrieved from the relative url<registry>/v2/<name>/manifests/<digest>
.MediaType
:application/vnd.oci.image.manifest.v1+json
orapplication/vnd.docker.distribution.manifest.v2+json
OS
: The operating system that this image is for. Values are as forGOOS
. [Note 1]Architecture
: The architecture this image is for. Values are as forGOARCH
. [Note 1]Annotations
: Annotations applied to the image.Labels
: Labels applied to the image
{
"Tags": ["<tag>", "<tag>"],
"Digest": "<digest>",
"MediaType": "<media type>",
"Images": [Image, ...] // No Tags fields
}
Tags
: List of tags applied to the image list. [Note 2]Digest
: The digest of the Docker manifest list or OCI image index. The contents can be retrieved from the relative url<registry>/v2/<name>/manifests/<digest>
.MediaType
:application/vnd.docker.distribution.manifest.list.v2+json
orapplication/vnd.oci.image.index.v1+json
Images
: Matching images within the image list. For example, if an image list has images for thei386
,amd64
, andarm64
architectures andarchitecture=amd64
is present in the query, only the amd64 image will be included.
For images within an image list,
the architecture and OS matched by architecture=
and os=
queries
and returned as Architecture
and OS
in the JSON result
MAY either be the values extracted from the image's
Image Configuration,
or the values from the
platform object
in the image index.
The behavior when these don't match is undefined.
For Tags
fields in images and image lists,
when tag
parameters in the query limits the set of returned images,
an implementation MAY return only include tags matching the tags in the query.
(This is specified to avoid an implementation having to do excessive work to find all tags.)
Otherwise, all tags applied to the image SHOULD be returned.
The specification here is general, but is primarily used by Flatpak. If implementing this specification for use only by Flatpak clients, the following notes may be helpful in optimizing and simplifying the implementation.
- Flatpak only uses the
/index/static endpoint
, and not the/index/dynamic
endpoint - Flatpak will always include the following parameters in the query:
label:org.flatpak.ref:exists=1
architecture=<ARCHITECTURE>
os=<OS>
tag=<TAG>
- Flatpak does not query on annotations or use the annotations in the returned result. (Early versions of Flatpak OCI support used annotations instead of labels, but Flatpak switched to using labels for Docker Image compatibility, given poor registry support for OCI Images at that time.)
- Flatpak retrieves images by digest and does not care about the tag structure of the returned result. It does not care whether images are returned in Images or ImageLists, and does not look at the Tags field.