diff --git a/docs/requirements.txt b/docs/requirements.txt
index 6966869c7054c18810eb323772b93ba5a42cefc5..cd7c3062a54c674c19c4d182d65b5a2882606fcf 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1 +1,2 @@
 sphinx
+sphinxcontrib-openapi
diff --git a/docs/source/conf.py b/docs/source/conf.py
index dacdfe51d1cedfe1b5b8baff87f552729808d594..f5dd3d43d2312c65969dc841ef4da5f05135107f 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -39,6 +39,7 @@ release = '0.0'
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
 extensions = [
+    "sphinxcontrib.openapi",
 ]
 
 # Add any paths that contain templates here, relative to this directory.
diff --git a/docs/source/designs/backup-recovery.rst b/docs/source/designs/backup-recovery.rst
index 15bef9861fc271ceb08533b6a52a50ff8e49d1b1..7c9c07d3d21a6c8df59da9b0404bf7dd2c905a86 100644
--- a/docs/source/designs/backup-recovery.rst
+++ b/docs/source/designs/backup-recovery.rst
@@ -205,7 +205,7 @@ Backup operations resume as usual from this point using the existing on-grid sta
 External Interfaces
 ~~~~~~~~~~~~~~~~~~~
 
-
+.. openapi:: ./backup-recovery.yaml
 
 Data Integrity
 ~~~~~~~~~~~~~~
diff --git a/docs/source/designs/backup-recovery.yaml b/docs/source/designs/backup-recovery.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fd73f61c7eb9a0deb02d8e2e7959a95ad1c81878
--- /dev/null
+++ b/docs/source/designs/backup-recovery.yaml
@@ -0,0 +1,72 @@
+openapi: "3.1.0"
+info:
+  title: "Backup / Recovery"
+  description: |
+    This API allows backup and recovery of ZKAPAuthorizer internal state.
+  version: "1.0.0"
+paths:
+  /storage-plugins/privatestorageio-zkapauthz-v1/recover:
+    post:
+      description: |
+        Recover ZKAPAuthorizer state from a previously configured backup.
+        This is only valid when ZKAPAuthorizer has no local state yet.
+      requestBody:
+        content:
+          application/json:
+            schema:
+              type: object
+              properties:
+                recovery-capability:
+                  type: "string"
+                  description: |
+                    The Tahoe-LAFS read-only capability for the recovery data.
+                    This is a capability previously returned by the backup
+                    endpoint.
+      responses:
+        200:
+          description: |
+            Recovery from the backup has been completed.
+          content:
+            application/json:
+              schema:
+                type: "object"
+                property: {}
+
+  /storage-plugins/privatestorageio-zkapauthz-v1/backup:
+    post:
+      description: |
+        Configure ZKAPAuthorizer to maintain an on-grid backup of its state or
+        return the existing configuration details if it has already been
+        configured to do so.
+      responses:
+        201:
+          description: |
+            A new backup has just been configured.  Details about that backup
+            will be returned.
+          content:
+            application/json:
+              schema:
+                type: object
+                properties:
+                  recovery-capability:
+                    type: "string"
+                    description: |
+                      The Tahoe-LAFS read-only capability for the recovery
+                      data.  This is the capability which can be submitted in
+                      order to initiate a recovery from the backup.
+
+        200:
+          description: |
+            A backup has already been configured.  Details about that backup
+            will be returned.
+          content:
+            application/json:
+              schema:
+                type: object
+                properties:
+                  recovery-capability:
+                    type: "string"
+                    description: |
+                      The Tahoe-LAFS read-only capability for the recovery
+                      data.  This is the capability which can be submitted in
+                      order to initiate a recovery from the backup.
diff --git a/shell.nix b/shell.nix
index c7ed13786f4d7d394237bcf99009423c2b22c639..be375c6c2ec867afad6b5762c2c8946ba6e7cc90 100644
--- a/shell.nix
+++ b/shell.nix
@@ -17,10 +17,12 @@ let
     ];
     requirements =
       ''
+      ${builtins.readFile ./docs/requirements.txt}
       ${builtins.readFile ./requirements/test.in}
       ${zkapauthorizer.requirements}
       '';
   };
+
 in
 pkgs.mkShell {
   # Avoid leaving .pyc all over the source tree when manually triggering tests