diff --git a/astro.config.mjs b/astro.config.mjs
index d82197eb..6025d70f 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -45,6 +45,13 @@ export default defineConfig({
label: "Introduction",
link: "specs",
},
+ {
+ label: "Capabilities",
+ collapsed: true,
+ autogenerate: {
+ directory: "specs/capabilities",
+ },
+ },
{
label: "Subscriptions",
collapsed: true,
diff --git a/schema.yml b/schema.yml
index 13205552..63fd0e96 100644
--- a/schema.yml
+++ b/schema.yml
@@ -202,6 +202,20 @@ paths:
security:
- podcast_auth:
- read:subscriptions
+ /capabilities:
+ get:
+ tags:
+ - Capabilities
+ summary: Retrieve server capabilities
+ description: Returns a summary of features and core specification versions supported by the server.
+ operationId: getCapabilities
+ responses:
+ "200":
+ description: Successful operation
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Capabilities"
components:
responses:
Unauthorized:
@@ -573,6 +587,48 @@ components:
deletion_id: 25
status: SUCCESS
message: Subscription deleted successfully
+ Capabilities:
+ type: object
+ properties:
+ capabilities:
+ type: object
+ description: |
+ The features supported by the server. The first object MUST be "urn:opa:core".
+ additionalProperties:
+ type: object
+ description: A map of versions for a specific feature.
+ additionalProperties:
+ type: object
+ required:
+ - status
+ - root
+ properties:
+ status:
+ type: string
+ enum: [STABLE, UNSTABLE, DEPRECATED]
+ root:
+ type: string
+ example:
+ urn:opa:core:
+ "0.0.1":
+ status: DEPRECATED
+ root: '/v0'
+ "1.0.0":
+ status: STABLE
+ root: '/v1'
+ "2.0.0":
+ status: UNSTABLE
+ root: '/v2'
+ urn:opa:extra:playcount:
+ "0.0.1":
+ status: DEPRECATED
+ root: '/v0/playcount'
+ "1.0.0":
+ status: STABLE
+ root: '/v1/playcount'
+ "2.0.0":
+ status: UNSTABLE
+ root: '/v2/playcount'
requestBodies:
FeedArray:
description: An array of feeds the user wants to subscribe to
@@ -604,4 +660,4 @@ components:
api_key:
type: apiKey
name: api_key
- in: header
+ in: header
\ No newline at end of file
diff --git a/src/content/docs/specs/capabilities/get-capabilities.mdx b/src/content/docs/specs/capabilities/get-capabilities.mdx
new file mode 100644
index 00000000..51ffc7e4
--- /dev/null
+++ b/src/content/docs/specs/capabilities/get-capabilities.mdx
@@ -0,0 +1,58 @@
+---
+title: Get capabilities
+description: An endpoint for querying server capabilities
+next: false
+sidebar:
+ order: 2
+---
+
+import CoreAction from "@partials/_core-action.mdx";
+
+
+
+```http title="Endpoint"
+GET /v1/capabilities
+```
+
+The capabilities endpoint exposes details about the features a server supports. Capabilities are scoped by `urn` and MUST contain the following:
+
+- Each supported version of the feature.
+- The `status` of the feature version: `STABLE` | `UNSTABLE` | `DEPRECATED`.
+- The `root` relative URL the feature can be accessed at.
+
+Each `capabilities` response MUST contain a `urn:opa:core` object that lists the versions of the Open Podcast API the server supports. Additional capabilities MAY be returned as separate `urn` objects with supported versions.
+
+## Example 200 response
+
+```json
+{
+ "urn:opa:core": {
+ "0.0.1": {
+ "status": "DEPRECATED",
+ "root": "/v0"
+ },
+ "1.0.0": {
+ "status": "STABLE",
+ "root": "/v1"
+ },
+ "2.0.0": {
+ "status": "UNSTABLE",
+ "root": "/v2"
+ }
+ },
+ "urn:opa:extra:playcount": {
+ "0.0.1": {
+ "status": "DEPRECATED",
+ "root": "/v0/playcount"
+ },
+ "1.0.0": {
+ "status": "STABLE",
+ "root": "/v1/playcount"
+ },
+ "2.0.0": {
+ "status": "UNSTABLE",
+ "root": "/v2/playcount"
+ }
+ }
+}
+```
diff --git a/src/content/docs/specs/capabilities/index.mdx b/src/content/docs/specs/capabilities/index.mdx
new file mode 100644
index 00000000..57c26a39
--- /dev/null
+++ b/src/content/docs/specs/capabilities/index.mdx
@@ -0,0 +1,29 @@
+---
+title: Capabilities endpoint
+description: An endpoint for querying server capabilities
+prev: false
+sidebar:
+ label: Overview
+ order: 1
+---
+
+import CoreEndpoint from "@partials/_core-endpoint.mdx";
+
+
+
+The Open Podcast API is subject to change over time. To ensure backwards compatibility and effective communication of server capabilities, the API specification MUST be versioned in a consistent way.
+
+The specification follows the [Semantic versioning model](https://semver.org/). Each version of the specification MUST adhere to the following rules:
+
+**Major** versions
+: A major version update indicates that a breaking change has occurred. This is reserved for the deprecation, addition, or renaming of **core** capabilities.
+
+**Minor** versions
+: A minor version update indicates that a new **optional** feature has been added or that a **core** feature has received a non-breaking change. This can include the deprecation or addition of parameters or behaviors.
+
+**Patch** versions
+: A patch version update indicates that a small non-breaking change has been made to clarify a feature or address an issue with wording.
+
+## Backwards compatibility
+
+To maintain backwards compatibility between **minor** versions, no parameters nor endpoints may be removed without a **major** version change. Fields may be deprecated in favor of new behaviors, but when queried by an older client the server MUST respond with a compatible response.