diff --git a/keyserver/src/creators/upload-creator.js b/keyserver/src/creators/upload-creator.js
--- a/keyserver/src/creators/upload-creator.js
+++ b/keyserver/src/creators/upload-creator.js
@@ -22,6 +22,7 @@
   | {
       +storage: 'blob_service',
       +blobHolder: string,
+      +blobHash: string,
     };
 
 export type UploadInput = {
@@ -52,6 +53,11 @@
       content.storage === 'keyserver' ? content.buffer : Buffer.alloc(0);
     const blobHolder =
       content.storage === 'blob_service' ? content.blobHolder : undefined;
+    const blobHash =
+      content.storage === 'blob_service' ? content.blobHash : undefined;
+    if ((blobHolder && !blobHash) || (!blobHolder && blobHash)) {
+      throw new ServerError('invalid_parameters');
+    }
     const uri = makeUploadURI(blobHolder, id, secret);
 
     return {
@@ -75,6 +81,7 @@
           ...dimensions,
           loop,
           blobHolder,
+          blobHash,
           encryptionKey,
           thumbHash,
         }),
diff --git a/keyserver/src/uploads/uploads.js b/keyserver/src/uploads/uploads.js
--- a/keyserver/src/uploads/uploads.js
+++ b/keyserver/src/uploads/uploads.js
@@ -116,6 +116,7 @@
   width: t.Number,
   height: t.Number,
   blobHolder: t.String,
+  blobHash: t.String,
   encryptionKey: t.String,
   mimeType: t.String,
   loop: t.maybe(t.Boolean),
@@ -137,13 +138,21 @@
     throw new ServerError('invalid_parameters');
   }
 
-  const { filename, blobHolder, encryptionKey, mimeType, width, height, loop } =
-    request;
+  const {
+    filename,
+    blobHolder,
+    blobHash,
+    encryptionKey,
+    mimeType,
+    width,
+    height,
+    loop,
+  } = request;
   const uploadInfo: UploadInput = {
     name: filename,
     mime: mimeType,
     mediaType,
-    content: { storage: 'blob_service', blobHolder },
+    content: { storage: 'blob_service', blobHolder, blobHash },
     encryptionKey,
     dimensions: { width, height },
     loop: loop ?? false,
diff --git a/lib/types/media-types.js b/lib/types/media-types.js
--- a/lib/types/media-types.js
+++ b/lib/types/media-types.js
@@ -88,6 +88,7 @@
   ...Dimensions,
   +filename: string,
   +blobHolder: string,
+  +blobHash: string,
   +encryptionKey: string,
   +mimeType: string,
   +loop?: boolean,
diff --git a/native/input/input-state-container.react.js b/native/input/input-state-container.react.js
--- a/native/input/input-state-container.react.js
+++ b/native/input/input-state-container.react.js
@@ -1264,6 +1264,7 @@
       filename,
       mimeType,
       blobHolder: newHolder,
+      blobHash,
       encryptionKey,
       loop: loop ?? false,
       ...(thumbHash ? { thumbHash } : null),
diff --git a/web/input/input-state-container.react.js b/web/input/input-state-container.react.js
--- a/web/input/input-state-container.react.js
+++ b/web/input/input-state-container.react.js
@@ -1179,6 +1179,7 @@
       ...input.dimensions,
       loop: input.loop ?? false,
       blobHolder: newHolder,
+      blobHash,
       encryptionKey: input.encryptionKey,
       mimeType: input.file.type,
       filename: input.file.name,