diff --git a/.gitattributes b/.gitattributes index a2363ebf92..279878b8e4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ cmd/build.go export-subst *.go diff=golang +Documentation/reference/api.md linguist-generated diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f031ede90a..736ccb2be3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,11 +38,6 @@ jobs: printf '::error file=%s,title=Bad Filename::Disallowed character in file name\n' "$file" done exit $(git ls-files -- ':/:*[<>:"|?*]*' | wc -l) - - name: Check API Reference - if: ${{ !cancelled() && steps.checkout.conclusion == 'success' }} - run: | - npx widdershins --search false --language_tabs 'python:Python' 'go:Golang' 'javascript:Javascript' --summary ./openapi.yaml -o ./Documentation/reference/api.md - git diff --exit-code - name: Check Container Versions if: ${{ !cancelled() && steps.checkout.conclusion == 'success' }} run: | diff --git a/Documentation/reference/api.md b/Documentation/reference/api.md index ebc74ab43e..224226725e 100644 --- a/Documentation/reference/api.md +++ b/Documentation/reference/api.md @@ -1,5 +1,5 @@ --- -title: ClairV4 v1.1 +title: Clair Container Analyzer v1.2.0 language_tabs: - python: Python - go: Golang @@ -8,7 +8,8 @@ language_clients: - python: "" - go: "" - javascript: "" -toc_footers: [] +toc_footers: + - External documentation includes: [] search: false highlight_theme: darkula @@ -18,265 +19,22 @@ headingLevel: 2 -

ClairV4 v1.1

+

Clair Container Analyzer v1.2.0

> Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu. -ClairV4 is a set of cooperating microservices which scan, index, and match your container's content with known vulnerabilities. +Clair is a set of cooperating microservices which can index and match a container image's content with known vulnerabilities. + +**Note:** Any endpoints tagged "internal" are documented for completeness but are considered exempt from versioning. Email: Clair Team Web: Clair Team License: Apache License 2.0 -

Notifier

- -## DeleteNotification - - - -> Code samples - -```python -import requests -headers = { - 'Accept': 'application/json' -} - -r = requests.delete('/notifier/api/v1/notification/{notification_id}', headers = headers) - -print(r.json()) - -``` - -```go -package main - -import ( - "bytes" - "net/http" -) - -func main() { - - headers := map[string][]string{ - "Accept": []string{"application/json"}, - } - - data := bytes.NewBuffer([]byte{jsonReq}) - req, err := http.NewRequest("DELETE", "/notifier/api/v1/notification/{notification_id}", data) - req.Header = headers - - client := &http.Client{} - resp, err := client.Do(req) - // ... -} - -``` - -```javascript - -const headers = { - 'Accept':'application/json' -}; - -fetch('/notifier/api/v1/notification/{notification_id}', -{ - method: 'DELETE', - - headers: headers -}) -.then(function(res) { - return res.json(); -}).then(function(body) { - console.log(body); -}); - -``` - -`DELETE /notifier/api/v1/notification/{notification_id}` - -Issues a delete of the provided notification id and all associated notifications. After this delete clients will no longer be able to retrieve notifications. - -

Parameters

- -|Name|In|Type|Required|Description| -|---|---|---|---|---| -|notification_id|path|string|false|A notification ID returned by a callback| - -> Example responses - -> 400 Response - -```json -{ - "code": "string", - "message": "string" -} -``` - -

Responses

- -|Status|Meaning|Description|Schema| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|OK|None| -|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad Request|[Error](#schemaerror)| -|405|[Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5)|Method Not Allowed|[Error](#schemaerror)| -|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal Server Error|[Error](#schemaerror)| - - - -## Retrieve a paginated result of notifications for the provided id. - - - -> Code samples - -```python -import requests -headers = { - 'Accept': 'application/json' -} - -r = requests.get('/notifier/api/v1/notification/{notification_id}', headers = headers) - -print(r.json()) - -``` - -```go -package main - -import ( - "bytes" - "net/http" -) - -func main() { - - headers := map[string][]string{ - "Accept": []string{"application/json"}, - } - - data := bytes.NewBuffer([]byte{jsonReq}) - req, err := http.NewRequest("GET", "/notifier/api/v1/notification/{notification_id}", data) - req.Header = headers - - client := &http.Client{} - resp, err := client.Do(req) - // ... -} - -``` - -```javascript - -const headers = { - 'Accept':'application/json' -}; - -fetch('/notifier/api/v1/notification/{notification_id}', -{ - method: 'GET', - - headers: headers -}) -.then(function(res) { - return res.json(); -}).then(function(body) { - console.log(body); -}); - -``` - -`GET /notifier/api/v1/notification/{notification_id}` - -By performing a GET with a notification_id as a path parameter, the client will retrieve a paginated response of notification objects. - -

Parameters

- -|Name|In|Type|Required|Description| -|---|---|---|---|---| -|notification_id|path|string|false|A notification ID returned by a callback| -|page_size|query|int|false|The maximum number of notifications to deliver in a single page.| -|next|query|string|false|The next page to fetch via id. Typically this number is provided on initial response in the page.next field. The first GET request may omit this field.| - -> Example responses - -> 200 Response - -```json -{ - "page": { - "size": 100, - "next": "1b4d0db2-e757-4150-bbbb-543658144205" - }, - "notifications": [ - { - "id": "5e4b387e-88d3-4364-86fd-063447a6fad2", - "manifest": "sha256:35c102085707f703de2d9eaad8752d6fe1b8f02b5d2149f1d8357c9cc7fb7d0a", - "reason": "added", - "vulnerability": { - "name": "CVE-2009-5155", - "fixed_in_version": "v0.0.1", - "links": "http://link-to-advisory", - "description": "In the GNU C Library (aka glibc or libc6) before 2.28, parse_reg_exp in posix/regcomp.c misparses alternatives, which allows attackers to cause a denial of service (assertion failure and application exit) or trigger an incorrect result by attempting a regular-expression match.\"", - "normalized_severity": "Unknown", - "package": { - "id": "10", - "name": "libapt-pkg5.0", - "version": "1.6.11", - "kind": "binary", - "normalized_version": "", - "arch": "x86", - "module": "", - "cpe": "", - "source": { - "id": "9", - "name": "apt", - "version": "1.6.11", - "kind": "source", - "source": null - } - }, - "distribution": { - "id": "1", - "did": "ubuntu", - "name": "Ubuntu", - "version": "18.04.3 LTS (Bionic Beaver)", - "version_code_name": "bionic", - "version_id": "18.04", - "arch": "", - "cpe": "", - "pretty_name": "Ubuntu 18.04.3 LTS" - }, - "repository": { - "id": "string", - "name": "string", - "key": "string", - "uri": "string", - "cpe": "string" - } - } - } - ] -} -``` - -

Responses

- -|Status|Meaning|Description|Schema| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A paginated list of notifications|[PagedNotifications](#schemapagednotifications)| -|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad Request|[Error](#schemaerror)| -|405|[Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5)|Method Not Allowed|[Error](#schemaerror)| -|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal Server Error|[Error](#schemaerror)| +# Authentication - +- HTTP Authentication, scheme: bearer Clair's authentication scheme. -

Indexer

+

indexer

## Index the contents of a Manifest @@ -287,8 +45,8 @@ This operation does not require authentication ```python import requests headers = { - 'Content-Type': 'application/json', - 'Accept': 'application/json' + 'Content-Type': 'application/vnd.clair.manifest.v1+json', + 'Accept': 'application/vnd.clair.index_report.v1+json' } r = requests.post('/indexer/api/v1/index_report', headers = headers) @@ -308,8 +66,8 @@ import ( func main() { headers := map[string][]string{ - "Content-Type": []string{"application/json"}, - "Accept": []string{"application/json"}, + "Content-Type": []string{"application/vnd.clair.manifest.v1+json"}, + "Accept": []string{"application/vnd.clair.index_report.v1+json"}, } data := bytes.NewBuffer([]byte{jsonReq}) @@ -328,22 +86,19 @@ const inputBody = '{ "hash": "sha256:fc84b5febd328eccaa913807716887b3eb5ed08bc22cc6933a9ebf82766725e3", "layers": [ { - "hash": "sha256:fc84b5febd328eccaa913807716887b3eb5ed08bc22cc6933a9ebf82766725e3", + "hash": "sha256:2f077db56abccc19f16f140f629ae98e904b4b7d563957a7fc319bd11b82ba36", "uri": "https://storage.example.com/blob/2f077db56abccc19f16f140f629ae98e904b4b7d563957a7fc319bd11b82ba36", "headers": { - "property1": [ - "string" - ], - "property2": [ - "string" + "Authoriztion": [ + "Bearer hunter2" ] } } ] }'; const headers = { - 'Content-Type':'application/json', - 'Accept':'application/json' + 'Content-Type':'application/vnd.clair.manifest.v1+json', + 'Accept':'application/vnd.clair.index_report.v1+json' }; fetch('/indexer/api/v1/index_report', @@ -371,14 +126,11 @@ By submitting a Manifest object to this endpoint Clair will fetch the layers, sc "hash": "sha256:fc84b5febd328eccaa913807716887b3eb5ed08bc22cc6933a9ebf82766725e3", "layers": [ { - "hash": "sha256:fc84b5febd328eccaa913807716887b3eb5ed08bc22cc6933a9ebf82766725e3", + "hash": "sha256:2f077db56abccc19f16f140f629ae98e904b4b7d563957a7fc319bd11b82ba36", "uri": "https://storage.example.com/blob/2f077db56abccc19f16f140f629ae98e904b4b7d563957a7fc319bd11b82ba36", "headers": { - "property1": [ - "string" - ], - "property2": [ - "string" + "Authoriztion": [ + "Bearer hunter2" ] } } @@ -390,7 +142,7 @@ By submitting a Manifest object to this endpoint Clair will fetch the layers, sc |Name|In|Type|Required|Description| |---|---|---|---|---| -|body|body|[Manifest](#schemamanifest)|true|none| +|body|body|[manifest](#schemamanifest)|true|Manifest to index.| > Example responses @@ -398,51 +150,17 @@ By submitting a Manifest object to this endpoint Clair will fetch the layers, sc ```json { - "manifest_hash": "sha256:fc84b5febd328eccaa913807716887b3eb5ed08bc22cc6933a9ebf82766725e3", - "state": "IndexFinished", - "packages": { - "10": { - "id": "10", - "name": "libapt-pkg5.0", - "version": "1.6.11", - "kind": "binary", - "normalized_version": "", - "arch": "x86", - "module": "", - "cpe": "", - "source": { - "id": "9", - "name": "apt", - "version": "1.6.11", - "kind": "source", - "source": null - } - } - }, - "distributions": { - "1": { - "id": "1", - "did": "ubuntu", - "name": "Ubuntu", - "version": "18.04.3 LTS (Bionic Beaver)", - "version_code_name": "bionic", - "version_id": "18.04", - "arch": "", - "cpe": "", - "pretty_name": "Ubuntu 18.04.3 LTS" - } - }, - "environments": { - "10": [ - { - "package_db": "var/lib/dpkg/status", - "introduced_in": "sha256:35c102085707f703de2d9eaad8752d6fe1b8f02b5d2149f1d8357c9cc7fb7d0a", - "distribution_id": "1" - } - ] - }, + "manifest_hash": null, + "state": "string", + "err": "string", "success": true, - "err": "" + "packages": {}, + "distributions": {}, + "repository": {}, + "environments": { + "property1": [], + "property2": [] + } } ``` @@ -450,16 +168,26 @@ By submitting a Manifest object to this endpoint Clair will fetch the layers, sc |Status|Meaning|Description|Schema| |---|---|---|---| -|201|[Created](https://tools.ietf.org/html/rfc7231#section-6.3.2)|IndexReport Created|[IndexReport](#schemaindexreport)| -|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad Request|[Error](#schemaerror)| -|405|[Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5)|Method Not Allowed|[Error](#schemaerror)| -|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal Server Error|[Error](#schemaerror)| +|201|[Created](https://tools.ietf.org/html/rfc7231#section-6.3.2)|IndexReport created. + +Clients may want to avoid reading the body if simply submitting the manifest for later vulnerability reporting.|[index_report](#schemaindex_report)| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad Request|[error](#schemaerror)| +|412|[Precondition Failed](https://tools.ietf.org/html/rfc7232#section-4.2)|Precondition Failed|None| +|415|[Unsupported Media Type](https://tools.ietf.org/html/rfc7231#section-6.5.13)|Unsupported Media Type|[error](#schemaerror)| +|default|Default|Internal Server Error|[error](#schemaerror)| + +### Response Headers + +|Status|Header|Type|Format|Description| +|---|---|---|---|---| +|201|Location|string||HTTP [Location header](https://httpwg.org/specs/rfc9110.html#field.location)| +|201|Link|string||Web Linking [Link header](https://httpwg.org/specs/rfc8288.html#header)| -## Delete the IndexReport and associated information for the given Manifest hashes, if they exist. +## Delete the referenced manifests. @@ -468,8 +196,8 @@ This operation does not require authentication ```python import requests headers = { - 'Content-Type': 'application/json', - 'Accept': 'application/json' + 'Content-Type': 'application/vnd.clair.bulk_delete.v1+json', + 'Accept': 'application/vnd.clair.bulk_delete.v1+json' } r = requests.delete('/indexer/api/v1/index_report', headers = headers) @@ -489,8 +217,8 @@ import ( func main() { headers := map[string][]string{ - "Content-Type": []string{"application/json"}, - "Accept": []string{"application/json"}, + "Content-Type": []string{"application/vnd.clair.bulk_delete.v1+json"}, + "Accept": []string{"application/vnd.clair.bulk_delete.v1+json"}, } data := bytes.NewBuffer([]byte{jsonReq}) @@ -509,8 +237,8 @@ const inputBody = '[ "sha256:fc84b5febd328eccaa913807716887b3eb5ed08bc22cc6933a9ebf82766725e3" ]'; const headers = { - 'Content-Type':'application/json', - 'Accept':'application/json' + 'Content-Type':'application/vnd.clair.bulk_delete.v1+json', + 'Accept':'application/vnd.clair.bulk_delete.v1+json' }; fetch('/indexer/api/v1/index_report', @@ -539,11 +267,11 @@ Given a Manifest's content addressable hash, any data related to it will be remo ] ``` -

Parameters

+

Parameters

|Name|In|Type|Required|Description| |---|---|---|---|---| -|body|body|[BulkDelete](#schemabulkdelete)|true|none| +|body|body|[bulk_delete](#schemabulk_delete)|true|Array of manifest digests to delete.| > Example responses @@ -555,19 +283,26 @@ Given a Manifest's content addressable hash, any data related to it will be remo ] ``` -

Responses

+

Responses

|Status|Meaning|Description|Schema| |---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|OK|[BulkDelete](#schemabulkdelete)| -|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad Request|[Error](#schemaerror)| -|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal Server Error|[Error](#schemaerror)| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|Successfully deleted manifests.|[bulk_delete](#schemabulk_delete)| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad Request|[error](#schemaerror)| +|415|[Unsupported Media Type](https://tools.ietf.org/html/rfc7231#section-6.5.13)|Unsupported Media Type|[error](#schemaerror)| +|default|Default|Internal Server Error|[error](#schemaerror)| + +### Response Headers + +|Status|Header|Type|Format|Description| +|---|---|---|---|---| +|200|Clair-Error|string||This is a trailer containing any errors encountered while writing the response.| -## Delete the IndexReport and associated information for the given Manifest hash, if exists. +## Delete the referenced manifest. @@ -576,10 +311,10 @@ This operation does not require authentication ```python import requests headers = { - 'Accept': 'application/json' + 'Accept': 'application/vnd.clair.error.v1+json' } -r = requests.delete('/indexer/api/v1/index_report/{manifest_hash}', headers = headers) +r = requests.delete('/indexer/api/v1/index_report/{digest}', headers = headers) print(r.json()) @@ -596,11 +331,11 @@ import ( func main() { headers := map[string][]string{ - "Accept": []string{"application/json"}, + "Accept": []string{"application/vnd.clair.error.v1+json"}, } data := bytes.NewBuffer([]byte{jsonReq}) - req, err := http.NewRequest("DELETE", "/indexer/api/v1/index_report/{manifest_hash}", data) + req, err := http.NewRequest("DELETE", "/indexer/api/v1/index_report/{digest}", data) req.Header = headers client := &http.Client{} @@ -613,10 +348,10 @@ func main() { ```javascript const headers = { - 'Accept':'application/json' + 'Accept':'application/vnd.clair.error.v1+json' }; -fetch('/indexer/api/v1/index_report/{manifest_hash}', +fetch('/indexer/api/v1/index_report/{digest}', { method: 'DELETE', @@ -630,15 +365,15 @@ fetch('/indexer/api/v1/index_report/{manifest_hash}', ``` -`DELETE /indexer/api/v1/index_report/{manifest_hash}` +`DELETE /indexer/api/v1/index_report/{digest}` Given a Manifest's content addressable hash, any data related to it will be removed it it exists. -

Parameters

+

Parameters

|Name|In|Type|Required|Description| |---|---|---|---|---| -|manifest_hash|path|[Digest](#schemadigest)|true|A digest of a manifest that has been indexed previous to this request.| +|digest|path|[digest](#schemadigest)|true|OCI-compatible digest of a referred object.| > Example responses @@ -651,19 +386,20 @@ Given a Manifest's content addressable hash, any data related to it will be remo } ``` -

Responses

+

Responses

|Status|Meaning|Description|Schema| |---|---|---|---| -|204|[No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5)|OK|None| -|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad Request|[Error](#schemaerror)| -|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal Server Error|[Error](#schemaerror)| +|204|[No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5)|Success|None| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad Request|[error](#schemaerror)| +|415|[Unsupported Media Type](https://tools.ietf.org/html/rfc7231#section-6.5.13)|Unsupported Media Type|[error](#schemaerror)| +|default|Default|Internal Server Error|[error](#schemaerror)| -## Retrieve an IndexReport for the given Manifest hash if exists. +## Retrieve the IndexReport for the referenced manifest. @@ -672,10 +408,10 @@ This operation does not require authentication ```python import requests headers = { - 'Accept': 'application/json' + 'Accept': 'application/vnd.clair.index_report.v1+json' } -r = requests.get('/indexer/api/v1/index_report/{manifest_hash}', headers = headers) +r = requests.get('/indexer/api/v1/index_report/{digest}', headers = headers) print(r.json()) @@ -692,11 +428,11 @@ import ( func main() { headers := map[string][]string{ - "Accept": []string{"application/json"}, + "Accept": []string{"application/vnd.clair.index_report.v1+json"}, } data := bytes.NewBuffer([]byte{jsonReq}) - req, err := http.NewRequest("GET", "/indexer/api/v1/index_report/{manifest_hash}", data) + req, err := http.NewRequest("GET", "/indexer/api/v1/index_report/{digest}", data) req.Header = headers client := &http.Client{} @@ -709,10 +445,10 @@ func main() { ```javascript const headers = { - 'Accept':'application/json' + 'Accept':'application/vnd.clair.index_report.v1+json' }; -fetch('/indexer/api/v1/index_report/{manifest_hash}', +fetch('/indexer/api/v1/index_report/{digest}', { method: 'GET', @@ -726,15 +462,15 @@ fetch('/indexer/api/v1/index_report/{manifest_hash}', ``` -`GET /indexer/api/v1/index_report/{manifest_hash}` +`GET /indexer/api/v1/index_report/{digest}` -Given a Manifest's content addressable hash an IndexReport will be retrieved if exists. +Given a Manifest's content addressable hash, an IndexReport will be retrieved if it exists. -

Parameters

+

Parameters

|Name|In|Type|Required|Description| |---|---|---|---|---| -|manifest_hash|path|[Digest](#schemadigest)|true|A digest of a manifest that has been indexed previous to this request.| +|digest|path|[digest](#schemadigest)|true|OCI-compatible digest of a referred object.| > Example responses @@ -742,63 +478,35 @@ Given a Manifest's content addressable hash an IndexReport will be retrieved if ```json { - "manifest_hash": "sha256:fc84b5febd328eccaa913807716887b3eb5ed08bc22cc6933a9ebf82766725e3", - "state": "IndexFinished", - "packages": { - "10": { - "id": "10", - "name": "libapt-pkg5.0", - "version": "1.6.11", - "kind": "binary", - "normalized_version": "", - "arch": "x86", - "module": "", - "cpe": "", - "source": { - "id": "9", - "name": "apt", - "version": "1.6.11", - "kind": "source", - "source": null - } - } - }, - "distributions": { - "1": { - "id": "1", - "did": "ubuntu", - "name": "Ubuntu", - "version": "18.04.3 LTS (Bionic Beaver)", - "version_code_name": "bionic", - "version_id": "18.04", - "arch": "", - "cpe": "", - "pretty_name": "Ubuntu 18.04.3 LTS" - } - }, - "environments": { - "10": [ - { - "package_db": "var/lib/dpkg/status", - "introduced_in": "sha256:35c102085707f703de2d9eaad8752d6fe1b8f02b5d2149f1d8357c9cc7fb7d0a", - "distribution_id": "1" - } - ] - }, + "manifest_hash": null, + "state": "string", + "err": "string", "success": true, - "err": "" + "packages": {}, + "distributions": {}, + "repository": {}, + "environments": { + "property1": [], + "property2": [] + } } ``` -

Responses

+

Responses

|Status|Meaning|Description|Schema| |---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|IndexReport retrieved|[IndexReport](#schemaindexreport)| -|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad Request|[Error](#schemaerror)| -|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|Not Found|[Error](#schemaerror)| -|405|[Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5)|Method Not Allowed|[Error](#schemaerror)| -|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|Internal Server Error|[Error](#schemaerror)| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|IndexReport retrieved|[index_report](#schemaindex_report)| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|Bad Request|[error](#schemaerror)| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|Not Found|[error](#schemaerror)| +|415|[Unsupported Media Type](https://tools.ietf.org/html/rfc7231#section-6.5.13)|Unsupported Media Type|[error](#schemaerror)| +|default|Default|Internal Server Error|[error](#schemaerror)| + +### Response Headers + +|Status|Header|Type|Format|Description| +|---|---|---|---|---| +|200|Clair-Error|string||This is a trailer containing any errors encountered while writing the response.|