diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java
index 4f880fcb27dd6d99b330ba99776e9248d38f98d6..b37abf05f512764a26f85dd7aedbcba90bade446 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java
@@ -18,6 +18,9 @@
 
 package org.bigbluebutton.api;
 
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -29,11 +32,20 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.TreeMap;
 import java.util.Set;
-import java.util.concurrent.*;
-
-import org.bigbluebutton.api.domain.*;
+import java.util.TreeMap;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.apache.http.client.utils.URIBuilder;
+import org.bigbluebutton.api.domain.Meeting;
+import org.bigbluebutton.api.domain.Recording;
+import org.bigbluebutton.api.domain.User;
+import org.bigbluebutton.api.domain.UserSession;
 import org.bigbluebutton.api.messaging.MessageListener;
 import org.bigbluebutton.api.messaging.RedisStorageService;
 import org.bigbluebutton.api.messaging.converters.messages.DestroyMeetingMessage;
@@ -47,6 +59,8 @@ import org.bigbluebutton.api.messaging.messages.MeetingDestroyed;
 import org.bigbluebutton.api.messaging.messages.MeetingEnded;
 import org.bigbluebutton.api.messaging.messages.MeetingStarted;
 import org.bigbluebutton.api.messaging.messages.RegisterUser;
+import org.bigbluebutton.api.messaging.messages.StunTurnInfoRequested;
+import org.bigbluebutton.api.messaging.messages.UpdateRecordingStatus;
 import org.bigbluebutton.api.messaging.messages.UserJoined;
 import org.bigbluebutton.api.messaging.messages.UserJoinedVoice;
 import org.bigbluebutton.api.messaging.messages.UserLeft;
@@ -60,7 +74,6 @@ import org.bigbluebutton.api2.IBbbWebApiGWApp;
 import org.bigbluebutton.common.messages.Constants;
 import org.bigbluebutton.common.messages.SendStunTurnInfoReplyMessage;
 import org.bigbluebutton.presentation.PresentationUrlDownloadService;
-import org.bigbluebutton.api.messaging.messages.StunTurnInfoRequested;
 import org.bigbluebutton.web.services.RegisteredUserCleanupTimerTask;
 import org.bigbluebutton.web.services.callback.CallbackUrlService;
 import org.bigbluebutton.web.services.callback.MeetingEndedEvent;
@@ -447,6 +460,14 @@ public class MeetingService implements MessageListener {
         message.meetingId, message.parentMeetingId);
     }
   }
+  
+  private void processUpdateRecordingStatus(UpdateRecordingStatus message) {
+    Meeting m = getMeeting(message.meetingId);
+      // Set only once
+      if (m != null && message.recording && !m.haveRecordingMarks()) {
+          m.setHaveRecordingMarks(message.recording);
+      }
+  }
 
   private void processEndBreakoutRoom(EndBreakoutRoom message) {
     processEndMeeting(new EndMeeting(message.breakoutMeetingId));
@@ -570,12 +591,18 @@ public class MeetingService implements MessageListener {
       Map<String, String> metadata = m.getMetadata();
       if (metadata.containsKey(END_CALLBACK_URL)) {
         String callbackUrl = metadata.get(END_CALLBACK_URL);
+        try {
+            callbackUrl = new URIBuilder(new URI(callbackUrl)).addParameter("recordingmarks", m.haveRecordingMarks() ? "true" : "false").build().toURL().toString();
+        } catch (MalformedURLException e) {
+            log.error("Malformed URL in callback url=[{}]", callbackUrl);
+        } catch (URISyntaxException e) {
+            log.error("URI Syntax error in callback url=[{}]", callbackUrl);
+            e.printStackTrace();
+        }
         callbackUrlService.handleMessage(new MeetingEndedEvent(callbackUrl));
       }
 
       processRemoveEndedMeeting(message);
-
-      return;
     }
   }
 
@@ -861,6 +888,8 @@ public class MeetingService implements MessageListener {
           processStunTurnInfoRequested((StunTurnInfoRequested) message);
         } else if (message instanceof CreateBreakoutRoom) {
           processCreateBreakoutRoom((CreateBreakoutRoom) message);
+        } else if (message instanceof UpdateRecordingStatus) {
+          processUpdateRecordingStatus((UpdateRecordingStatus) message);
         }
       }
     };
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java
index 99ec4c9ed56522ed1fe982a65f304ac495c1e4d5..e3e1f66894877f6cc649b22b59d58375ffc81564 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java
@@ -51,6 +51,7 @@ public class Meeting {
 	private boolean record;
 	private boolean autoStartRecording = false;
 	private boolean allowStartStopRecording = false;
+	private boolean haveRecordingMarks = false;
 	private boolean webcamsOnlyForModerator = false;
 	private String dialNumber;
 	private String defaultAvatarURL;
@@ -212,7 +213,16 @@ public class Meeting {
 	public Boolean isBreakout() {
 	  return isBreakout;
 	}
+	
+	   
+    public void setHaveRecordingMarks(boolean marks) {
+        haveRecordingMarks = marks;
+    }
 
+    public boolean haveRecordingMarks() {
+        return  haveRecordingMarks;
+    }
+    
 	public String getName() {
 		return name;
 	}
@@ -495,7 +505,7 @@ public class Meeting {
     		this.allowStartStopRecording = allow;
     		return this;
     	}
-    	
+    
         public Builder withWebcamsOnlyForModerator(boolean only) {
             this.webcamsOnlyForModerator = only;
             return this;
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UpdateRecordingStatus.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UpdateRecordingStatus.java
new file mode 100644
index 0000000000000000000000000000000000000000..ba77958dccd430ab4f8f3677c7a7888b6460fec3
--- /dev/null
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UpdateRecordingStatus.java
@@ -0,0 +1,11 @@
+package org.bigbluebutton.api.messaging.messages;
+
+public class UpdateRecordingStatus implements IMessage {
+    public final String meetingId;
+    public final Boolean recording;
+
+    public UpdateRecordingStatus(String meetingId, Boolean recording) {
+        this.meetingId = meetingId;
+        this.recording = recording;
+    }
+}
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/web/services/callback/CallbackUrlService.java b/bbb-common-web/src/main/java/org/bigbluebutton/web/services/callback/CallbackUrlService.java
index 8044f00e88ba466363fc7d527e9e5a091c74f60a..c06145228676ab423b86508f068988d5d05b9865 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/web/services/callback/CallbackUrlService.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/web/services/callback/CallbackUrlService.java
@@ -1,24 +1,22 @@
 package org.bigbluebutton.web.services.callback;
 
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.methods.HttpGet;
-import org.apache.http.entity.ContentType;
 import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
 import org.apache.http.impl.nio.client.HttpAsyncClients;
-import org.apache.http.nio.client.methods.HttpAsyncMethods;
-import org.apache.http.nio.client.methods.ZeroCopyConsumer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.concurrent.*;
-
 public class CallbackUrlService {
 	private static Logger log = LoggerFactory.getLogger(CallbackUrlService.class);
 
@@ -119,10 +117,10 @@ public class CallbackUrlService {
 	}
 
 	private boolean fetchCallbackUrl(final String callbackUrl) {
-		log.info("Calling callback url {}", callbackUrl);
-
 		String finalUrl = followRedirect(callbackUrl, 0, callbackUrl);
 
+		log.info("Calling callback url {}", finalUrl);
+
 		if (finalUrl == null) return false;
 
 		boolean success = false;
diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala
index fdac5722337d9ed07af247fa19b1fd21e6003420..700e83a626b9e1451b22ef6d9110459e4b9796f7 100755
--- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala
+++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala
@@ -87,6 +87,8 @@ class ReceivedJsonMsgHdlrActor(val msgFromAkkaAppsEventBus: MsgFromAkkaAppsEvent
         route[UserRoleChangedEvtMsg](envelope, jsonNode)
       case CreateBreakoutRoomSysCmdMsg.NAME =>
         route[CreateBreakoutRoomSysCmdMsg](envelope, jsonNode)
+      case RecordingStatusChangedEvtMsg.NAME =>
+        route[RecordingStatusChangedEvtMsg](envelope, jsonNode)
 
       case _ =>
         //log.debug("************ Cannot route envelope name " + envelope.name)
diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala
index dfc45af7d8c4ded5365c7fae5563bfded515b78a..b034d89b228bdc14f15d2c88dac5a2f0c6ad8694 100755
--- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala
+++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala
@@ -36,6 +36,7 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW)
       case m: UserBroadcastCamStartedEvtMsg => handleUserBroadcastCamStartedEvtMsg(m)
       case m: UserBroadcastCamStoppedEvtMsg => handleUserBroadcastCamStoppedEvtMsg(m)
       case m: CreateBreakoutRoomSysCmdMsg => handleCreateBreakoutRoomSysCmdMsg(m)
+      case m: RecordingStatusChangedEvtMsg => handleRecordingStatusChangedEvtMsg(m)
       case _ => log.error("***** Cannot handle " + msg.envelope.name)
     }
   }
@@ -69,6 +70,10 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW)
      ))
 
   }
+  
+  def handleRecordingStatusChangedEvtMsg(msg: RecordingStatusChangedEvtMsg): Unit = {
+    olgMsgGW.handle(new UpdateRecordingStatus(msg.header.meetingId, msg.body.recording));
+  }
 
   def handleCheckAlivePongSysMsg(msg: CheckAlivePongSysMsg): Unit = {
     olgMsgGW.handle(new org.bigbluebutton.api.messaging.messages.KeepAliveReply(msg.body.system, msg.body.timestamp))