diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c
index 11828ce328..c865dd5070 100644
--- a/src/mod/event_handlers/mod_rayo/mod_rayo.c
+++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c
@@ -4199,11 +4199,31 @@ static struct rayo_actor *xmpp_stream_client_locate(struct xmpp_stream *stream,
 	return actor;
 }
 
+/**
+ * Handle stream resource binding
+ * @param stream the new stream
+ */
+static int on_xmpp_stream_bind(struct xmpp_stream *stream)
+{
+	if (!xmpp_stream_is_s2s(stream)) {
+		/* client belongs to stream */
+		struct rayo_client *client = rayo_client_create(xmpp_stream_get_jid(stream), xmpp_stream_get_jid(stream), PS_OFFLINE, rayo_client_send, NULL);
+		if (client) {
+			xmpp_stream_set_private(stream, client);
+		} else {
+			/* this went really bad... */
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create client entity!\n");
+			return 0;
+		}
+	}
+	return 1;
+}
+
 /**
  * Handle new stream creation
  * @param stream the new stream
  */
-static void on_xmpp_stream_ready(struct xmpp_stream *stream)
+static int on_xmpp_stream_ready(struct xmpp_stream *stream)
 {
 	if (xmpp_stream_is_s2s(stream)) {
 		if (xmpp_stream_is_incoming(stream)) {
@@ -4214,6 +4234,7 @@ static void on_xmpp_stream_ready(struct xmpp_stream *stream)
 			} else {
 				/* this went really bad... */
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create peer server entity!\n");
+				return 0;
 			}
 		} else {
 			/* send directed presence to domain */
@@ -4227,16 +4248,8 @@ static void on_xmpp_stream_ready(struct xmpp_stream *stream)
 			iks_insert_cdata(x, "chat", 4);
 			RAYO_SEND_MESSAGE(globals.server, xmpp_stream_get_jid(stream), presence);
 		}
-	} else {
-		/* client belongs to stream */
-		struct rayo_client *client = rayo_client_create(xmpp_stream_get_jid(stream), xmpp_stream_get_jid(stream), PS_OFFLINE, rayo_client_send, NULL);
-		if (client) {
-			xmpp_stream_set_private(stream, client);
-		} else {
-			/* this went really bad... */
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create client entity!\n");
-		}
 	}
+	return 1;
 }
 
 /**
@@ -4486,7 +4499,7 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing shared secret for %s domain.  Server dialback will not work\n", name);
 			}
 
-			globals.xmpp_context = xmpp_stream_context_create(name, shared_secret, on_xmpp_stream_ready, on_xmpp_stream_recv, on_xmpp_stream_destroy);
+			globals.xmpp_context = xmpp_stream_context_create(name, shared_secret, on_xmpp_stream_bind, on_xmpp_stream_ready, on_xmpp_stream_recv, on_xmpp_stream_destroy);
 			globals.server = rayo_server_create(name);
 
 			/* set up TLS */
diff --git a/src/mod/event_handlers/mod_rayo/xmpp_streams.c b/src/mod/event_handlers/mod_rayo/xmpp_streams.c
index 23a7387db6..fcc3c76213 100644
--- a/src/mod/event_handlers/mod_rayo/xmpp_streams.c
+++ b/src/mod/event_handlers/mod_rayo/xmpp_streams.c
@@ -1,6 +1,6 @@
 /*
  * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2013, Grasshopper
+ * Copyright (C) 2013-2015, Grasshopper
  *
  * Version: MPL 1.1
  *
@@ -55,6 +55,8 @@ struct xmpp_stream_context {
 	switch_hash_t *users;
 	/** shared secret for server dialback */
 	const char *dialback_secret;
+	/** callback when a new resource is bound */
+	xmpp_stream_bind_callback bind_callback;
 	/** callback when a new stream is ready */
 	xmpp_stream_ready_callback ready_callback;
 	/** callback when a stream is destroyed */
@@ -539,17 +541,19 @@ static iks *on_iq_set_xmpp_session(struct xmpp_stream *stream, iks *node)
 
 	switch(stream->state) {
 		case XSS_RESOURCE_BOUND: {
-			reply = iks_new_iq_result(node);
-			stream->state = XSS_READY;
+			if (context->ready_callback && !context->ready_callback(stream)) {
+				reply = iks_new_error(node, STANZA_ERROR_INTERNAL_SERVER_ERROR);
+				stream->state = XSS_ERROR;
+			} else {
+				reply = iks_new_iq_result(node);
+				stream->state = XSS_READY;
 
-			/* add to available streams */
-			switch_mutex_lock(context->streams_mutex);
-			switch_core_hash_insert(context->routes, stream->jid, stream);
-			switch_mutex_unlock(context->streams_mutex);
-
-			if (context->ready_callback) {
-				context->ready_callback(stream);
+				/* add to available streams */
+				switch_mutex_lock(context->streams_mutex);
+				switch_core_hash_insert(context->routes, stream->jid, stream);
+				switch_mutex_unlock(context->streams_mutex);
 			}
+
 			break;
 		}
 		case XSS_AUTHENTICATED:
@@ -574,6 +578,7 @@ static iks *on_iq_set_xmpp_bind(struct xmpp_stream *stream, iks *node)
 
 	switch(stream->state) {
 		case XSS_AUTHENTICATED: {
+			struct xmpp_stream_context *context = stream->context;
 			iks *bind = iks_find(node, "bind");
 			iks *x;
 			/* get optional client resource ID */
@@ -585,14 +590,19 @@ static iks *on_iq_set_xmpp_bind(struct xmpp_stream *stream, iks *node)
 				switch_uuid_str(resource_id_buf, sizeof(resource_id_buf));
 				resource_id = switch_core_strdup(stream->pool, resource_id_buf);
 			}
-			stream->jid = switch_core_sprintf(stream->pool, "%s/%s", stream->jid, resource_id);
-			stream->state = XSS_RESOURCE_BOUND;
 
-			/* create reply */
-			reply = iks_new_iq_result(node);
-			x = iks_insert(reply, "bind");
-			iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_BIND);
-			iks_insert_cdata(iks_insert(x, "jid"), stream->jid, strlen(stream->jid));
+			stream->jid = switch_core_sprintf(stream->pool, "%s/%s", stream->jid, resource_id);
+			if (context->bind_callback && !context->bind_callback(stream)) {
+				stream->jid = NULL;
+				reply = iks_new_error(node, STANZA_ERROR_CONFLICT);
+			} else {
+				stream->state = XSS_RESOURCE_BOUND;
+
+				reply = iks_new_iq_result(node);
+				x = iks_insert(reply, "bind");
+				iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_BIND);
+				iks_insert_cdata(iks_insert(x, "jid"), stream->jid, strlen(stream->jid));
+			}
 			break;
 		}
 		default:
@@ -732,16 +742,16 @@ static void on_stream_dialback_result_valid(struct xmpp_stream *stream, iks *nod
 	/* TODO check domain pair and allow access if pending request exists */
 	switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, valid dialback result\n", stream->jid, stream->address, stream->port);
 
-	/* this stream is routable */
-	stream->state = XSS_READY;
+	if (context->ready_callback && !context->ready_callback(stream)) {
+		stream->state = XSS_ERROR;
+	} else {
+		/* this stream is routable */
+		stream->state = XSS_READY;
 
-	/* add to available streams */
-	switch_mutex_lock(context->streams_mutex);
-	switch_core_hash_insert(context->routes, stream->jid, stream);
-	switch_mutex_unlock(context->streams_mutex);
-
-	if (context->ready_callback) {
-		context->ready_callback(stream);
+		/* add to available streams */
+		switch_mutex_lock(context->streams_mutex);
+		switch_core_hash_insert(context->routes, stream->jid, stream);
+		switch_mutex_unlock(context->streams_mutex);
 	}
 }
 
@@ -816,6 +826,18 @@ static void on_stream_dialback_result_key(struct xmpp_stream *stream, iks *node)
 		return;
 	}
 
+	/* this stream is not routable */
+	stream->state = XSS_READY;
+	stream->jid = switch_core_strdup(stream->pool, from);
+
+	if (context->ready_callback && !context->ready_callback(stream)) {
+		iks *error = iks_new_error(node, STANZA_ERROR_INTERNAL_SERVER_ERROR);
+		iks_send(stream->parser, error);
+		iks_delete(error);
+		stream->state = XSS_ERROR;
+		return;
+	}
+
 	/* TODO validate key */
 	reply = iks_new("db:result");
 	iks_insert_attrib(reply, "from", to);
@@ -823,14 +845,6 @@ static void on_stream_dialback_result_key(struct xmpp_stream *stream, iks *node)
 	iks_insert_attrib(reply, "type", "valid");
 	iks_send(stream->parser, reply);
 	iks_delete(reply);
-
-	/* this stream is not routable */
-	stream->state = XSS_READY;
-	stream->jid = switch_core_strdup(stream->pool, from);
-
-	if (context->ready_callback) {
-		context->ready_callback(stream);
-	}
 }
 
 /**
@@ -1014,6 +1028,11 @@ static void on_inbound_server_stream_start(struct xmpp_stream *stream, iks *node
 		case XSS_SECURE:
 			break;
 		case XSS_AUTHENTICATED: {
+			if (context->ready_callback && !context->ready_callback(stream)) {
+				stream->state = XSS_ERROR;
+				break;
+			}
+
 			/* all set */
 			xmpp_send_server_header_features(stream);
 			stream->state = XSS_READY;
@@ -1022,10 +1041,6 @@ static void on_inbound_server_stream_start(struct xmpp_stream *stream, iks *node
 			switch_mutex_lock(context->streams_mutex);
 			switch_core_hash_insert(context->routes, stream->jid, stream);
 			switch_mutex_unlock(context->streams_mutex);
-
-			if (context->ready_callback) {
-				context->ready_callback(stream);
-			}
 			break;
 		}
 		case XSS_SHUTDOWN:
@@ -1745,12 +1760,13 @@ void xmpp_stream_context_dump(struct xmpp_stream_context *context, switch_stream
  * Create a new XMPP stream context
  * @param domain for new streams
  * @param domain_secret domain shared secret for server dialback
+ * @param bind_cb callback function when a resource is bound to a new stream
  * @param ready callback function when new stream is ready
  * @param recv callback function when a new stanza is received
  * @param destroy callback function when a stream is destroyed
  * @return the context
  */
-struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy)
+struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_bind_callback bind_cb, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy)
 {
 	switch_memory_pool_t *pool;
 	struct xmpp_stream_context *context;
@@ -1762,6 +1778,7 @@ struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const
 	switch_core_hash_init(&context->routes);
 	switch_core_hash_init(&context->streams);
 	context->dialback_secret = switch_core_strdup(context->pool, domain_secret);
+	context->bind_callback = bind_cb;
 	context->ready_callback = ready;
 	context->destroy_callback = destroy;
 	context->recv_callback = recv;
diff --git a/src/mod/event_handlers/mod_rayo/xmpp_streams.h b/src/mod/event_handlers/mod_rayo/xmpp_streams.h
index a07c75d025..242f392543 100644
--- a/src/mod/event_handlers/mod_rayo/xmpp_streams.h
+++ b/src/mod/event_handlers/mod_rayo/xmpp_streams.h
@@ -1,6 +1,6 @@
 /*
  * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
- * Copyright (C) 2013, Grasshopper
+ * Copyright (C) 2013-2015, Grasshopper
  *
  * Version: MPL 1.1
  *
@@ -32,11 +32,12 @@
 struct xmpp_stream;
 struct xmpp_stream_context;
 
-typedef void (* xmpp_stream_ready_callback)(struct xmpp_stream *stream);
+typedef int (* xmpp_stream_bind_callback)(struct xmpp_stream *stream);
+typedef int (* xmpp_stream_ready_callback)(struct xmpp_stream *stream);
 typedef void (* xmpp_stream_recv_callback)(struct xmpp_stream *stream, iks *stanza);
 typedef void (* xmpp_stream_destroy_callback)(struct xmpp_stream *stream);
 
-extern struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy);
+extern struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_bind_callback bind_cb, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy);
 extern void xmpp_stream_context_add_cert(struct xmpp_stream_context *context, const char *cert_pem_file);
 extern void xmpp_stream_context_add_key(struct xmpp_stream_context *context, const char *key_pem_file);
 extern void xmpp_stream_context_add_user(struct xmpp_stream_context *context, const char *user, const char *password);