diff --git a/geoip.js b/geoip.js
new file mode 100644
index 0000000..4668dd7
--- /dev/null
+++ b/geoip.js
@@ -0,0 +1,88 @@
+// $Id$
+
+/**
+ * @file
+ * JSON Callback for GeoIP country code lookups.
+ */
+
+Drupal.geoip = {
+
+  /**
+   * Make a country lookup request.
+   *
+   * @param callback
+   *   Callback function which will be called when the request completes.
+   * @param param
+   *   Optional, value that will be passed to the callback after the data.
+   */
+  lookupCountry: function(callback, param) {
+    // Save a request if we've got the country stored in a cookie.
+    if (cookie = Drupal.geoip.readCookie('geoip_country')) {
+      callback(cookie, param);
+      return;
+    }
+
+    // If there's a debug IP address in URL, pass that back to the server.
+    var url =  Drupal.settings.basePath + 'geoip/json/country',
+      debug = window.location.search.match(/geoip_debug=([0-9]*).([0-9]*).([0-9]*).([0-9]*)/);
+    if (debug !== null) {
+      url += '?'+ debug[0];
+    }
+
+    $.ajax({
+      url: url,
+      dataType: 'json',
+      success: function(data) {
+        var expires = null;
+        if (Drupal.settings.geoip.lifetime) {
+          expires = new Date();
+          expires.setDate(expires.getDate() + Drupal.settings.geoip.lifetime);
+        }
+        Drupal.geoip.createCookie('geoip_country', data, expires);
+        callback(data, param);
+      }
+    });
+  },
+
+  /**
+   * Creates a cookie.
+   *
+   * @param name
+   *   Name of the cookie.
+   * @param value
+   *   String value to store.
+   * @param expires
+   *   Optional Date object specifying when the cookie should expire.
+   */
+  createCookie: function(name, value, expires) {
+    var cookie = name + "=" + value + "; path=" + Drupal.settings.basePath;
+    if (expires && expires instanceof Date) {
+      cookie += "; expires=" + expires.toGMTString();
+    }
+    document.cookie = cookie;
+  },
+
+  /**
+   * Reads a cookie.
+   *
+   * @param name
+   *   Name of the cookie.
+   *
+   * @return
+   *   The value of the cookie, or null if none was found.
+   */
+  readCookie: function(name) {
+    var nameEQ = name + "=";
+    var ca = document.cookie.split(';');
+    for (var i = 0; i < ca.length; i++) {
+      var c = ca[i];
+      while (c.charAt(0) == ' ') {
+        c = c.substring(1,c.length);
+      }
+      if (c.indexOf(nameEQ) == 0) {
+        return c.substring(nameEQ.length, c.length);
+      }
+    }
+    return null;
+  }
+};
\ No newline at end of file
diff --git a/geoip.module b/geoip.module
index 062b25a..01a3225 100644
--- a/geoip.module
+++ b/geoip.module
@@ -6,6 +6,16 @@
  */
 
 /**
+ * Implementation of hook_init().
+ */
+function geoip_init() {
+  // Disable caching on JSON request.
+  if ($_GET['q'] == 'geoip/json/country') {
+    $GLOBALS['conf']['cache'] = CACHE_DISABLED;
+  }
+}
+
+/**
  * Implementation of hook_menu().
  */
 function geoip_menu() {
@@ -17,7 +27,12 @@ function geoip_menu() {
     'access arguments' => array('administer site configuration'),
     'file' => 'geoip.admin.inc',
   );
-
+  $items['geoip/json/country'] = array(
+    'page callback' => 'geoip_json_country',
+    'page arguments' => array(3),
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK,
+  );
   return $items;
 }
 
@@ -57,7 +72,7 @@ function geoip_requirements($phase) {
 }
 
 /**
- * Helper function to get the current ip address
+ * Helper function to get the current ip address.
  */
 function geoip_ip_address() {
   if (variable_get('geoip_debug', FALSE) && !empty($_GET['geoip_debug'])) {
