diff --git a/docs/swagger.yaml b/API/harbor/swagger.yaml
similarity index 100%
rename from docs/swagger.yaml
rename to API/harbor/swagger.yaml
diff --git a/API/scanner/scanner-adapter-openapi-v1.0.yaml b/API/scanner/scanner-adapter-openapi-v1.0.yaml
new file mode 100644
index 000000000..db71d4744
--- /dev/null
+++ b/API/scanner/scanner-adapter-openapi-v1.0.yaml
@@ -0,0 +1,389 @@
+openapi: 3.0.0
+info:
+  title: Harbor Scanner Adapter API
+  description: |
+    ## Overview
+
+    This API must be implemented in order to register a new artifact scanner in [Harbor](https://goharbor.io) registry.
+
+    The [/scan](#operation/AcceptScanRequest) and [/scan/{scan_request_id}/report](#operation/GetScanReport) operations are responsible for the actual scanning and return a scan report that is visible in the Harbor web console.
+
+    The [/scan](#operation/AcceptScanRequest) operation is asynchronous. It should enqueue the job for processing a scan request and return the identifier. This allows Harbor to poll a corresponding scan report with the
+    [/scan/{scan_request_id}/report](#operation/GetScanReport) operation. Harbor will call the
+    [/scan/{scan_request_id}/report](#operation/GetScanReport) operation periodically periodically until it returns 200 or 500 status codes.
+
+    The [/metadata](#operation/GetMetadata) operation allows a Harbor admin to configure and register a scanner
+    and discover its capabilities.
+
+    ## Supported consumed MIME types
+
+    - `application/vnd.oci.image.manifest.v1+json`
+    - `application/vnd.docker.distribution.manifest.v2+json`
+
+    ## Supported produced MIME types
+
+    - `application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0`
+    - `application/vnd.scanner.adapter.vuln.report.raw`
+  contact:
+    email: cncf-harbor-maintainers@lists.cncf.io
+  license:
+    name: Apache 2.0
+    url: http://www.apache.org/licenses/LICENSE-2.0.html
+  version: "1.0"
+servers:
+  - url: /api/v1
+security:
+  - BasicAuth: []
+  - BearerAuth: []
+paths:
+  /metadata:
+    get:
+      tags:
+        - Scanner
+      summary: Get scanner metadata
+      description: |
+        Used to fetch scanner's metadata and capabilities. The operation is invoked to build an index of scanners
+        capable of analysing a given type of artifacts and making sure that scan reports can be parsed and rendered.
+      operationId: GetMetadata
+      responses:
+        200:
+          description: Scanner's metadata and capabilities
+          content:
+            "application/vnd.scanner.adapter.metadata+json; version=1.0":
+              schema:
+                $ref: '#/components/schemas/ScannerAdapterMetadata'
+        500:
+          description: Internal server error
+          content:
+            "application/vnd.scanner.adapter.error+json; version=1.0":
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
+  /scan:
+    post:
+      tags:
+        - Scanner
+      summary: Accept artifact scanning request
+      description: |
+        A non-blocking operation which enqueues a scan job and returns immediately. It returns a unique
+        identifier which can be used to poll for generated scan reports by Harbor.
+      operationId: AcceptScanRequest
+      requestBody:
+        description: |
+          Contains data required to pull the given artifact and save it for scanning in the file system or any other
+          location accessible to the scanner.
+        content:
+          "application/vnd.scanner.adapter.scan.request+json; version=1.0":
+            schema:
+              $ref: '#/components/schemas/ScanRequest'
+      responses:
+        202:
+          description: Scan request accepted
+          content:
+            "application/vnd.scanner.adapter.scan.response+json; version=1.0":
+              schema:
+                $ref: "#/components/schemas/ScanResponse"
+        400:
+          description: Received invalid JSON or the wrong type of JSON values
+          content:
+            "application/vnd.scanner.adapter.error+json; version=1.0":
+              schema:
+                $ref: "#/components/schemas/ErrorResponse"
+        422:
+          description: Received invalid field
+          content:
+            "application/vnd.scanner.adapter.error+json; version=1.0":
+              schema:
+                $ref: "#/components/schemas/ErrorResponse"
+        500:
+          description: Internal server error
+          content:
+            "application/vnd.scanner.adapter.error+json; version=1.0":
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
+  /scan/{scan_request_id}/report:
+    get:
+      tags:
+        - Scanner
+      summary: Get scan report
+      description: |
+        Get a scan report for the given scan request identifier.
+
+        Clients will periodically poll this operation and check `$response.status` until its value equals `200` or `500`.
+      operationId: GetScanReport
+      parameters:
+        - name: scan_request_id
+          in: path
+          description: The identifier of the corresponding scan request
+          required: true
+          style: simple
+          explode: false
+          schema:
+            $ref: '#/components/schemas/ScanRequestId'
+        - name: Accept
+          in: header
+          schema:
+            type: string
+          example: "application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0"
+      responses:
+        200:
+          description: Scan report
+          content:
+            "application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0":
+              schema:
+                $ref: '#/components/schemas/HarborVulnerabilityReport'
+            "application/vnd.scanner.adapter.vuln.report.raw":
+              schema:
+                type: string
+                example: |
+                  {
+                    "vendor_specific": "vulnerabilities_report"
+                  }
+        302:
+          description: Status indicating the scan report is being generated and the request should be retried.
+          headers:
+            Refresh-After:
+              description: Indicates the interval after which the request should be retried.
+              schema:
+                type: integer
+        404:
+          description: Cannot find the corresponding scan request identifier
+        500:
+          description: Internal server error
+          content:
+            "application/vnd.scanner.adapter.error+json; version=1.0":
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
+components:
+  schemas:
+    Scanner:
+      type: object
+      properties:
+        name:
+          type: string
+          description: The name of the scanner.
+          example: Microscanner
+        vendor:
+          type: string
+          description: The name of the scanner's provider.
+          example: Aqua Security
+        version:
+          type: string
+          description: The version of the scanner.
+          example: 3.0.5
+      description: |
+        Basic scanner properties such as name, vendor, and version.
+    ScannerAdapterMetadata:
+      required:
+        - scanner
+        - capabilities
+      type: object
+      properties:
+        scanner:
+          $ref: '#/components/schemas/Scanner'
+        capabilities:
+          type: array
+          items:
+            $ref: '#/components/schemas/ScannerCapability'
+        properties:
+          $ref: "#/components/schemas/ScannerProperties"
+      description: |
+        Represents metadata of a Scanner Adapter which allows Harbor to lookup a scanner capable
+        of scanning a given Artifact stored in its registry and making sure that it
+        can interpret a returned result.
+    ScannerProperties:
+      type: object
+      additionalProperties:
+        type: string
+      example:
+        "harbor.scanner-adapter/scanner-type": "os-package-vulnerability"
+        "harbor.scanner-adapter/vulnerability-database-updated-at": "2019-08-13T08:16:33.345Z"
+      description: |
+        A set of custom properties that can further describe capabilities of a given scanner.
+    ScannerCapability:
+      description: |
+        Capability consists of the set of recognized artifact MIME types and the set of scanner report MIME types.
+        For example, a scanner capable of analyzing Docker images and producing a vulnerabilities report recognizable
+        by Harbor web console might be represented with the following capability:
+        - consumes MIME types:
+          - `application/vnd.oci.image.manifest.v1+json`
+          - `application/vnd.docker.distribution.manifest.v2+json`
+        - produces MIME types:
+          - `application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0`
+      required:
+        - consumes_mime_types
+        - produces_mime_types
+      type: object
+      properties:
+        consumes_mime_types:
+          type: array
+          items:
+            type: string
+          description: |
+            The set of MIME types of the artifacts supported by the scanner to produce the reports specified in the "produces_mime_types". A given
+            mime type should only be present in one capability item.
+          example:
+            - "application/vnd.oci.image.manifest.v1+json"
+            - "application/vnd.docker.distribution.manifest.v2+json"
+        produces_mime_types:
+          type: array
+          items:
+            type: string
+          description: |
+            The set of MIME types of reports generated by the scanner for the consumes_mime_types of the same capability record.
+          example:
+            - "application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0"
+    ScanRequest:
+      required:
+        - registry
+        - artifact
+      type: object
+      properties:
+        registry:
+          $ref: '#/components/schemas/Registry'
+        artifact:
+          $ref: '#/components/schemas/Artifact'
+    ScanResponse:
+      required:
+        - id
+      properties:
+        id:
+          $ref: '#/components/schemas/ScanRequestId'
+    ScanRequestId:
+      description: |
+        A unique identifier returned by the [/scan](#/operation/AcceptScanRequest] operations. The format of the
+        identifier is not imposed but it should be unique enough to prevent collisons when polling for scan reports.
+      type: string
+      example: "3fa85f64-5717-4562-b3fc-2c963f66afa6"
+    Registry:
+      type: object
+      properties:
+        url:
+          type: string
+          description: A base URL or the Docker Registry v2 API.
+          format: url
+          example: https://core.harbor.domain
+        authorization:
+          type: string
+          description: |
+            An optional value of the HTTP Authorization header sent with each request to the Docker Registry v2 API.
+            It's used to exchange Base64 encoded robot account credentials to a short lived JWT access token which
+            allows the underlying scanner to pull the artifact from the Docker Registry.
+          example: "Basic BASE64_ENCODED_CREDENTIALS"
+    Artifact:
+      type: object
+      properties:
+        repository:
+          type: string
+          description: The name of the Docker Registry repository containing the artifact.
+          example: library/mongo
+        digest:
+          type: string
+          description: The artifact's digest, consisting of an algorithm and hex portion.
+          example: "sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b"
+        mime_type:
+          type: string
+          description: The MIME type of the artifact.
+          example: "application/vnd.docker.distribution.manifest.v2+json"
+    HarborVulnerabilityReport:
+      type: object
+      properties:
+        generated_at:
+          type: string
+          format: 'date-time'
+        artifact:
+          $ref: '#/components/schemas/Artifact'
+        scanner:
+          $ref: '#/components/schemas/Scanner'
+        severity:
+          $ref: "#/components/schemas/Severity"
+        vulnerabilities:
+          type: array
+          items:
+            $ref: '#/components/schemas/VulnerabilityItem'
+    VulnerabilityItem:
+      type: object
+      properties:
+        id:
+          type: string
+          description: The unique identifier of the vulnerability.
+          example: CVE-2017-8283
+        package:
+          type: string
+          description: |
+            An operating system package containing the vulnerability.
+          example: dpkg
+        version:
+          type: string
+          description: |
+            The version of the package containing the vulnerability.
+          example: 1.17.27
+        fix_version:
+          type: string
+          description: |
+            The version of the package containing the fix if available.
+          example: 1.18.0
+        severity:
+          $ref: "#/components/schemas/Severity"
+        description:
+          type: string
+          description: |
+            The detailed description of the vulnerability.
+          example: |
+            dpkg-source in dpkg 1.3.0 through 1.18.23 is able to use a non-GNU patch program
+            and does not offer a protection mechanism for blank-indented diff hunks, which
+            allows remote attackers to conduct directory traversal attacks via a crafted
+            Debian source package, as demonstrated by using of dpkg-source on NetBSD.
+        links:
+          type: array
+          items:
+            type: string
+            format: uri
+          description: |
+            The list of links to the upstream databases with the full description of the vulnerability.
+          format: uri
+          example:
+            - https://security-tracker.debian.org/tracker/CVE-2017-8283
+    Severity:
+      type: string
+      description: |
+        A standard scale for measuring the severity of a vulnerability.
+
+        * `Unknown` - either a security problem that has not been assigned to a priority yet or a priority that the
+          scanner did not recognize.
+        * `Negligible` - technically a security problem, but is only theoretical in nature, requires a very special
+          situation, has almost no install base, or does no real damage.
+        * `Low` - a security problem, but is hard to exploit due to environment, requires a user-assisted attack,
+          a small install base, or does very little damage.
+        * `Medium` - a real security problem, and is exploitable for many people. Includes network daemon denial of
+          service attacks, cross-site scripting, and gaining user privileges.
+        * `High` - a real problem, exploitable for many people in a default installation. Includes serious remote denial
+          of service, local root privilege escalations, or data loss.
+        * `Critical` - a world-burning problem, exploitable for nearly all people in a default installation. Includes
+          remote root privilege escalations, or massive data loss.
+      example: Low
+      enum:
+        - None
+        - Unknown
+        - Negligible
+        - Low
+        - Medium
+        - High
+        - Critical
+    ErrorResponse:
+      type: object
+      properties:
+        error:
+          $ref: "#/components/schemas/Error"
+    Error:
+      type: object
+      properties:
+        message:
+          type: string
+          example: "Some unexpected error"
+  securitySchemes:
+    BasicAuth:
+      type: http
+      scheme: basic
+    BearerAuth:
+      type: http
+      scheme: bearer
diff --git a/Makefile b/Makefile
index 7966618cc..f531e6882 100644
--- a/Makefile
+++ b/Makefile
@@ -438,7 +438,7 @@ swagger_client:
 	wget -q http://central.maven.org/maven2/io/swagger/swagger-codegen-cli/2.3.1/swagger-codegen-cli-2.3.1.jar -O swagger-codegen-cli.jar
 	rm -rf harborclient
 	mkdir harborclient
-	java -jar swagger-codegen-cli.jar generate -i docs/swagger.yaml -l python -o harborclient
+	java -jar swagger-codegen-cli.jar generate -i API/harbor/swagger.yaml -l python -o harborclient
 	cd harborclient; python ./setup.py install
 	pip install docker -q
 	pip freeze
diff --git a/README.md b/README.md
index 040b0de15..ce81ac087 100644
--- a/README.md
+++ b/README.md
@@ -44,6 +44,11 @@ Harbor is hosted by the [Cloud Native Computing Foundation](https://cncf.io) (CN
 * **RESTful API**: RESTful APIs for most administrative operations, easy to integrate with external systems. An embedded Swagger UI is available for exploring and testing the API.
 * **Easy deployment**: Provide both an online and offline installer. In addition, a Helm Chart can be used to deploy Harbor on Kubernetes.
 
+## API
+
+* [Harbor RESTful API](https://editor.swagger.io/?url=https://raw.githubusercontent.com/goharbor/harbor/master/API/harbor/swagger.yaml): The APIs for most administrative operations of Harbor and can be used to perform integrations with Harbor programmatically. 
+* [Scanner Open API](https://editor.swagger.io/?url=https://raw.githubusercontent.com/goharbor/harbor/master/API/scanner/scanner-adapter-openapi-v1.0.yaml): This API must be implemented in order to register a new artifact scanner in Harbor registry. 
+
 ## Install & Run
 
 **System requirements:**
diff --git a/docs/configure_swagger.md b/docs/configure_swagger.md
index 50ca6247f..fd4c08d4d 100644
--- a/docs/configure_swagger.md
+++ b/docs/configure_swagger.md
@@ -14,7 +14,7 @@ From time to time, you may need to mannually test Harbor REST API. You can deplo
 
 * Download _prepare-swagger.sh_ and _swagger.yaml_ under the _docs_ directory to your local Harbor directory, e.g. **~/harbor**.
 ```sh
-  wget https://raw.githubusercontent.com/goharbor/harbor/master/docs/prepare-swagger.sh https://raw.githubusercontent.com/goharbor/harbor/master/docs/swagger.yaml
+  wget https://raw.githubusercontent.com/goharbor/harbor/master/docs/prepare-swagger.sh https://raw.githubusercontent.com/goharbor/harbor/master/API/harbor/swagger.yaml
 ```
 * Edit the script file _prepare-swagger.sh_.
 ```sh
diff --git a/make/photon/portal/Dockerfile b/make/photon/portal/Dockerfile
index 9dc834413..bc710655e 100644
--- a/make/photon/portal/Dockerfile
+++ b/make/photon/portal/Dockerfile
@@ -7,7 +7,7 @@ ENV NPM_CONFIG_REGISTRY=${npm_registry}
 
 COPY src/portal/package.json /build_dir
 COPY src/portal/package-lock.json /build_dir
-COPY ./docs/swagger.yaml /build_dir
+COPY ./API/harbor/swagger.yaml /build_dir
 
 RUN apt-get update \
     && apt-get install -y --no-install-recommends python-yaml=3.12-1 \
diff --git a/tests/swaggerchecker.sh b/tests/swaggerchecker.sh
index 83a05a5ae..4c5e3b864 100755
--- a/tests/swaggerchecker.sh
+++ b/tests/swaggerchecker.sh
@@ -4,9 +4,9 @@ set +e
 
 SWAGGER_ONLINE_VALIDATOR="http://online.swagger.io/validator"
 if [ $TRAVIS_EVENT_TYPE = "push" ]; then
-	HARBOR_SWAGGER_FILE="https://raw.githubusercontent.com/$TRAVIS_REPO_SLUG/$TRAVIS_COMMIT/docs/swagger.yaml"
+	HARBOR_SWAGGER_FILE="https://raw.githubusercontent.com/$TRAVIS_REPO_SLUG/$TRAVIS_COMMIT/API/harbor/swagger.yaml"
 elif [ $TRAVIS_EVENT_TYPE = "pull_request" ]; then
-	HARBOR_SWAGGER_FILE="https://raw.githubusercontent.com/$TRAVIS_PULL_REQUEST_SLUG/$TRAVIS_PULL_REQUEST_SHA/docs/swagger.yaml"
+	HARBOR_SWAGGER_FILE="https://raw.githubusercontent.com/$TRAVIS_PULL_REQUEST_SLUG/$TRAVIS_PULL_REQUEST_SHA/API/harbor/swagger.yaml"
 else
 	echo "* don't support this kinds of action ($TRAVIS_EVENT_TYPE), but don't fail the travis CI."
 	exit 0