diff --git a/exec/load/json-client.js b/exec/load/json-client.js
index ac01e8e826b8e0d717d49006fe214c20e368f70a..15cc8a2e8e36d97a1e36d199a7b1bfb01fb6b40e 100644
--- a/exec/load/json-client.js
+++ b/exec/load/json-client.js
@@ -14,20 +14,26 @@ load("json-sock.js");
 	-	JSONClient.cycle(); 
 	-	JSONClient.connect();
 	-	JSONClient.disconnect();
-	-	JSONClient.read();
-	-	JSONClient.pop();
-	-	JSONClient.shift();
-	-	JSONClient.write();
-	-	JSONClient.push();
-	-	JSONClient.unshift();
-	-	JSONClient.lock();
-	-	JSONClient.unlock();
-	-	JSONClient.subscribe();
-	-	JSONClient.unsubscribe();
-	-	JSONClient.status();
-	-	JSONClient.who();
-	-	JSONClient.ident();
+	-	JSONClient.read(scope,location,lock);
+	-	JSONClient.pop(scope,location,lock);
+	-	JSONClient.shift(scope,location,lock);
+	-	JSONClient.write(scope,location,lock);
+	-	JSONClient.push(scope,location,lock);
+	-	JSONClient.unshift(scope,location,lock);
+	-	JSONClient.lock(scope,location,lock);
+	-	JSONClient.unlock(scope,location);
+	-	JSONClient.subscribe(scope,location);
+	-	JSONClient.unsubscribe(scope,location);
+	-	JSONClient.status(scope,location);
+	-	JSONClient.who(scope,location);
+	-	JSONClient.ident(scope,username,password);
 	
+	NOTE: scope is the module or root service you wish to send the command to,
+	location is a dot-notated object property, and lock is one of the following:
+		LOCK_READ = 1
+		LOCK_WRITE = 2
+		LOCK_UNLOCK = -1
+		
 	indirect methods: these will generally be called automatically by the other methods
 	and you will not typically need to use them
 	
@@ -43,22 +49,14 @@ load("json-sock.js");
 	
 	sample usage:
 	
-		var LOCK_READ = 1;
-		var LOCK_WRITE = 2;
-		var UNLOCK = -1;
-	
 		load("json-client.js");
 		var client=new JSONClient(myServer,myPort);
 		
-		function callback(data) {
-			myData = data;
-		}
-		
 		while(1) {
 			doSomething();
-			client.lock("mydatabase.dong",LOCK_READ);
-			var dong=client.read("mydatabase.dong");
-			client.unlock("mydatabase.dong");
+			client.lock("myscript","mydatabase.dong",LOCK_READ);
+			var dong=client.read("myscript","mydatabase.dong");
+			client.unlock("myscript","mydatabase.dong");
 			print("look at my " + dong);
 			client.cycle();
 		}
@@ -130,7 +128,7 @@ function JSONClient(serverAddr,serverPort) {
 	
 	/* unlock an object */ 
 	this.unlock = function(scope,location) {
-		this.lock(scope, location, -1);
+		this.lock(scope,location,-1);
 	}
     
 	/* read object data (lock for reading or writing, blocking) */
@@ -143,6 +141,16 @@ function JSONClient(serverAddr,serverPort) {
 		return this.wait("RESPONSE");
     }
 	
+	/* read object keys (lock for reading or writing, blocking) */
+	this.keys=function(scope,location,lock) {
+		this.send(scope,"QUERY",{
+            oper:"KEYS",
+            location:location,
+			lock:lock
+        });
+		return this.wait("RESPONSE");
+	}
+	
 	/* shift object data (lock for reading or writing, blocking) */
     this.shift=function(scope,location,lock) {
 		this.send(scope,"QUERY",{
diff --git a/exec/load/json-db.js b/exec/load/json-db.js
index 23008c089a6e960a0d96c0f597220c760cbf417f..505b24984b243f4ac4be01176972044f88f37314 100644
--- a/exec/load/json-db.js
+++ b/exec/load/json-db.js
@@ -87,7 +87,8 @@ function JSONdb (fileName) {
 		SUBSCRIBE:8,
 		UNSUBSCRIBE:9,
 		WHO:10,
-		STATUS:11
+		STATUS:11,
+		KEYS:12
 	}
 	
 	/* error constants */
@@ -357,6 +358,27 @@ function JSONdb (fileName) {
             return false;
         }
     };
+
+	/* retrieve a list of object keys */
+	this.keys = function(client,record) {
+		var keys=[];
+		/* if the requested data does not exist, result is undefined */
+		if(record.data === undefined) {
+            send_packet(client,undefined,"RESPONSE");
+			return true;
+		}
+		/* if this client has this record locked, read */
+		if(record.info.lock[client.id]) {
+			for(var k in record.data[record.child_name])
+				keys.push(k);
+            send_packet(client,keys,"RESPONSE");
+			return true;
+		}
+        /* if there is no lock for this client, error */
+        else {
+            return false;
+        }
+	}
     
     /* remove a record from the database (requires WRITE_LOCK) */
     this.remove = function(client,record) {
@@ -619,6 +641,9 @@ function JSONdb (fileName) {
 			case "WRITE":
 				result=this.write(request.client,record,request.data);
 				break;
+			case "KEYS":
+				result=this.keys(request.client,record);
+				break;
 			case "PUSH":
 				result=this.push(request.client,record,request.data);
 				break;