diff --git a/bigbluebutton-html5/imports/api/presentation-upload-token/server/handlers/presentationUploadTokenPass.js b/bigbluebutton-html5/imports/api/presentation-upload-token/server/handlers/presentationUploadTokenPass.js
index ada7c2d43acb6024306249efc2ca161a25c8d49b..0859c5627ee31e93d33dbc06a50250f0128bd58a 100644
--- a/bigbluebutton-html5/imports/api/presentation-upload-token/server/handlers/presentationUploadTokenPass.js
+++ b/bigbluebutton-html5/imports/api/presentation-upload-token/server/handlers/presentationUploadTokenPass.js
@@ -27,6 +27,7 @@ export default function handlePresentationUploadTokenPass({ body, header }, meet
     filename,
     authzToken,
     failed: false,
+    used: false,
   };
 
   const cb = (err) => {
diff --git a/bigbluebutton-html5/imports/api/presentation-upload-token/server/methods.js b/bigbluebutton-html5/imports/api/presentation-upload-token/server/methods.js
index 1666146edd206db9f9eaa5e57c94398797587424..d417f740c88d9797edbc9672b03a9ef7795d459c 100644
--- a/bigbluebutton-html5/imports/api/presentation-upload-token/server/methods.js
+++ b/bigbluebutton-html5/imports/api/presentation-upload-token/server/methods.js
@@ -1,6 +1,8 @@
 import { Meteor } from 'meteor/meteor';
 import requestPresentationUploadToken from './methods/requestPresentationUploadToken';
+import setUsedToken from './methods/setUsedToken';
 
 Meteor.methods({
   requestPresentationUploadToken,
+  setUsedToken,
 });
diff --git a/bigbluebutton-html5/imports/api/presentation-upload-token/server/methods/setUsedToken.js b/bigbluebutton-html5/imports/api/presentation-upload-token/server/methods/setUsedToken.js
new file mode 100644
index 0000000000000000000000000000000000000000..a09c9d7c1f658c0198c7042a0d68f6e98450666c
--- /dev/null
+++ b/bigbluebutton-html5/imports/api/presentation-upload-token/server/methods/setUsedToken.js
@@ -0,0 +1,30 @@
+import PresentationUploadToken from '/imports/api/presentation-upload-token';
+import Logger from '/imports/startup/server/logger';
+import { check } from 'meteor/check';
+
+export default function setUsedToken(credentials, authzToken) {
+  const { meetingId, requesterUserId, requesterToken } = credentials;
+  check(meetingId, String);
+  check(requesterUserId, String);
+  check(requesterToken, String);
+
+  const payload = {
+    $set: {
+      used: true,
+    },
+  };
+  const cb = (err) => {
+    if (err) {
+      Logger.error(`Unable to set token as used : ${err}`);
+      return;
+    }
+
+    Logger.info(`Token: ${authzToken} has been set as used in meeting=${meetingId}`);
+  };
+
+  return PresentationUploadToken.update({
+    meetingId,
+    userId: requesterUserId,
+    authzToken,
+  }, payload, cb);
+}
diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/service.js b/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/service.js
index a293d18d38cbb7557605629efd9e2c2d25b1432c..a6bd269f2a669ae91e8e49a343767b2f6504e586 100644
--- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/service.js
+++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/service.js
@@ -62,74 +62,90 @@ const dispatchTogglePresentationDownloadable = (presentation, newState) => {
   makeCall('setPresentationDownloadable', presentation.id, newState);
 };
 
-const observePresentationConversion = (meetingId, filename, onConversion) =>
-  new Promise((resolve) => {
-    const conversionTimeout = setTimeout(() => {
-      onConversion({
-        done: true,
-        error: true,
-        status: 'TIMEOUT',
-      });
-    }, CONVERSION_TIMEOUT);
+const observePresentationConversion = (
+  meetingId,
+  filename,
+  onConversion,
+) => new Promise((resolve) => {
+  const conversionTimeout = setTimeout(() => {
+    onConversion({
+      done: true,
+      error: true,
+      status: 'TIMEOUT',
+    });
+  }, CONVERSION_TIMEOUT);
 
-    const didValidate = (doc) => {
-      clearTimeout(conversionTimeout);
-      resolve(doc);
-    };
+  const didValidate = (doc) => {
+    clearTimeout(conversionTimeout);
+    resolve(doc);
+  };
 
-    Tracker.autorun((c) => {
-      const query = Presentations.find({ meetingId });
+  Tracker.autorun((c) => {
+    const query = Presentations.find({ meetingId });
 
-      query.observe({
-        changed: (newDoc) => {
-          if (newDoc.name !== filename) return;
+    query.observe({
+      changed: (newDoc) => {
+        if (newDoc.name !== filename) return;
 
-          onConversion(newDoc.conversion);
+        onConversion(newDoc.conversion);
 
-          if (newDoc.conversion.done) {
-            c.stop();
-            didValidate(newDoc);
-          }
-        },
-      });
+        if (newDoc.conversion.done) {
+          c.stop();
+          didValidate(newDoc);
+        }
+      },
     });
   });
+});
 
-const requestPresentationUploadToken = (podId, meetingId, filename) =>
-  new Promise((resolve, reject) => {
-    makeCall('requestPresentationUploadToken', podId, filename);
-
-    let computation = null;
-    const timeout = setTimeout(() => {
-      computation.stop();
-      reject({ code: 408, message: 'requestPresentationUploadToken timeout' });
-    }, TOKEN_TIMEOUT);
-
-    Tracker.autorun((c) => {
-      computation = c;
-      const sub = Meteor.subscribe('presentation-upload-token', Auth.credentials, podId, filename);
-      if (!sub.ready()) return;
-
-      const PresentationToken = PresentationUploadToken.findOne({
-        podId,
-        meetingId,
-        filename,
-      });
+const requestPresentationUploadToken = (
+  podId,
+  meetingId,
+  filename,
+) => new Promise((resolve, reject) => {
+  makeCall('requestPresentationUploadToken', podId, filename);
+
+  let computation = null;
+  const timeout = setTimeout(() => {
+    computation.stop();
+    reject({ code: 408, message: 'requestPresentationUploadToken timeout' });
+  }, TOKEN_TIMEOUT);
+
+  Tracker.autorun((c) => {
+    computation = c;
+    const sub = Meteor.subscribe('presentation-upload-token', Auth.credentials, podId, filename);
+    if (!sub.ready()) return;
+
+    const PresentationToken = PresentationUploadToken.findOne({
+      podId,
+      meetingId,
+      filename,
+      used: false,
+    });
 
-      if (!PresentationToken || !('failed' in PresentationToken)) return;
+    if (!PresentationToken || !('failed' in PresentationToken)) return;
 
-      if (!PresentationToken.failed) {
-        clearTimeout(timeout);
-        resolve(PresentationToken.authzToken);
-      }
+    if (!PresentationToken.failed) {
+      clearTimeout(timeout);
+      resolve(PresentationToken.authzToken);
+    }
 
-      if (PresentationToken.failed) {
-        reject({ code: 401, message: 'requestPresentationUploadToken failed' });
-      }
-    });
+    if (PresentationToken.failed) {
+      reject({ code: 401, message: `requestPresentationUploadToken token ${PresentationToken.authzToken} failed` });
+    }
   });
+});
 
-const uploadAndConvertPresentation = (file, downloadable, podId, meetingId, endpoint, onUpload, onProgress, onConversion) => {
+const uploadAndConvertPresentation = (
+  file,
+  downloadable,
+  podId,
+  meetingId,
+  endpoint,
+  onUpload,
+  onProgress,
+  onConversion,
+) => {
   const data = new FormData();
   data.append('presentation_name', file.name);
   data.append('Filename', file.name);
@@ -148,7 +164,10 @@ const uploadAndConvertPresentation = (file, downloadable, podId, meetingId, endp
   };
 
   return requestPresentationUploadToken(podId, meetingId, file.name)
-    .then(token => futch(endpoint.replace('upload', `${token}/upload`), opts, onProgress))
+    .then((token) => {
+      makeCall('setUsedToken', token);
+      return futch(endpoint.replace('upload', `${token}/upload`), opts, onProgress);
+    })
     .then(() => observePresentationConversion(meetingId, file.name, onConversion))
     // Trap the error so we can have parallel upload
     .catch((error) => {
@@ -158,12 +177,15 @@ const uploadAndConvertPresentation = (file, downloadable, podId, meetingId, endp
     });
 };
 
-const uploadAndConvertPresentations = (presentationsToUpload, meetingId, podId, uploadEndpoint) =>
-  Promise.all(presentationsToUpload.map(p =>
-    uploadAndConvertPresentation(
-      p.file, p.isDownloadable, podId, meetingId, uploadEndpoint,
-      p.onUpload, p.onProgress, p.onConversion,
-    )));
+const uploadAndConvertPresentations = (
+  presentationsToUpload,
+  meetingId,
+  podId,
+  uploadEndpoint,
+) => Promise.all(presentationsToUpload.map(p => uploadAndConvertPresentation(
+  p.file, p.isDownloadable, podId, meetingId, uploadEndpoint,
+  p.onUpload, p.onProgress, p.onConversion,
+)));
 
 const setPresentation = (presentationId, podId) => makeCall('setPresentation', presentationId, podId);
 
@@ -173,8 +195,10 @@ const removePresentation = (presentationId, podId) => {
   makeCall('removePresentation', presentationId, podId);
 };
 
-const removePresentations = (presentationsToRemove, podId) =>
-  Promise.all(presentationsToRemove.map(p => removePresentation(p.id, podId)));
+const removePresentations = (
+  presentationsToRemove,
+  podId,
+) => Promise.all(presentationsToRemove.map(p => removePresentation(p.id, podId)));
 
 const persistPresentationChanges = (oldState, newState, uploadEndpoint, podId) => {
   const presentationsToUpload = newState.filter(p => !p.upload.done);