diff --git a/Keen.NET.Test/AccessKeyMock.cs b/Keen.NET.Test/AccessKeyMock.cs
new file mode 100644
index 0000000..682bfdd
--- /dev/null
+++ b/Keen.NET.Test/AccessKeyMock.cs
@@ -0,0 +1,35 @@
+using Keen.Core.AccessKey;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json.Linq;
+using Keen.Core;
+
+namespace Keen.Net.Test
+{
+    /// 
+    /// AccessKeyMock provides an implementation of IAccessKeys with a constructor that 
+    /// accepts delegates for each of the interface methods.
+    /// The purpose of this is to allow test methods to set up a customized
+    /// IAccessKeys for each test.
+    /// 
+    class AccessKeysMock : IAccessKeys
+    {
+        private readonly IProjectSettings _settings;
+        private readonly Func _createAccessKey;
+
+        public AccessKeysMock(IProjectSettings projSettings,
+             Func createAccessKey = null)
+        {
+            _settings = projSettings;
+            _createAccessKey = createAccessKey ?? ((p, k) => new JObject());
+        }
+
+        public Task CreateAccessKey(AccessKey accesskey)
+        {
+            return Task.Run(() => _createAccessKey(accesskey, _settings));
+        }
+    }
+}
diff --git a/Keen.NET.Test/AccessKeyTests.cs b/Keen.NET.Test/AccessKeyTests.cs
new file mode 100644
index 0000000..4a2e301
--- /dev/null
+++ b/Keen.NET.Test/AccessKeyTests.cs
@@ -0,0 +1,91 @@
+using Keen.Core;
+using Keen.Core.AccessKey;
+using Keen.Core.Query;
+using Newtonsoft.Json.Linq;
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Keen.Net.Test
+{
+    [TestFixture]
+    class AccessKeyTests : TestBase
+    {
+        [Test]
+        public void CreateAccessKey_Success()
+        {
+            var settings = new ProjectSettingsProvider(projectId: "X", masterKey: SettingsEnv.MasterKey); // Replace X with respective value
+            var client = new KeenClient(settings);
+
+            if (UseMocks)
+                client.AccessKeys = new AccessKeysMock(settings,
+                    createAccessKey: new Func((e, p) =>
+                    {
+                        Assert.True(p == settings, "Incorrect Settings");
+                        Assert.NotNull(e.Name, "Expected a name for the newly created Key");
+                        Assert.NotNull(e.Permitted, "Expected a list of high level actions this key can perform");
+                        Assert.NotNull(e.Options, "Expected an object containing more details about the key’s permitted and restricted functionality");
+                        if ((p == settings) && (e.Name == "TestAccessKey") && (e.IsActive) && e.Permitted.First() == "queries" && e.Options.CachedQueries.Allowed.First() == "my_cached_query")
+                            return new JObject();
+                        else
+                            throw new Exception("Unexpected value");
+                    }));
+
+            HashSet permissions = new HashSet() { "queries" };
+            List qFilters = new List() { new QueryFilter("customer.id", QueryFilter.FilterOperator.Equals(), "asdf12345z") };
+            CachedQueries cachedQueries = new CachedQueries();
+            cachedQueries.Allowed = new HashSet() { "my_cached_query" };
+            Options options = new Options()
+            {
+                Queries = new Core.AccessKey.Queries { Filters = qFilters },
+                CachedQueries = cachedQueries
+            };
+
+            Assert.DoesNotThrow(() => client.CreateAccessKey(new AccessKey { Name = "TestAccessKey", IsActive = true, Options = options, Permitted = permissions }));
+        }
+
+
+        [Test]
+        public void CreateAccessKey_With_All_Properties_Given_As_Null_Success()
+        {
+            var settings = new ProjectSettingsProvider(projectId: "X", masterKey: SettingsEnv.MasterKey); // Replace X with respective value
+            var client = new KeenClient(settings);
+
+            if (UseMocks)
+                client.AccessKeys = new AccessKeysMock(settings,
+                    createAccessKey: new Func((e, p) =>
+                    {
+                        Assert.True(p == settings, "Incorrect Settings");
+                        Assert.NotNull(e.Name, "Expected a name for the newly created Key");
+                        Assert.NotNull(e.Permitted, "Expected a list of high level actions this key can perform");
+                        Assert.NotNull(e.Options, "Expected an object containing more details about the key’s permitted and restricted functionality");
+                        if ((p == settings) && (e.Name == "TestAccessKey") && (e.IsActive) && e.Permitted.First() == "queries" && e.Options.CachedQueries.Allowed.First() == "my_cached_query")
+                            return new JObject();
+                        else
+                            throw new Exception("Unexpected value");
+                    }));
+
+            HashSet permissions = new HashSet() { "queries" };
+            List qFilters = new List() { new QueryFilter("customer.id", QueryFilter.FilterOperator.Equals(), "asdf12345z") };
+            CachedQueries cachedQueries = new CachedQueries() { Allowed = null, Blocked = null };
+            SavedQueries savedQuaries = new SavedQueries() { Allowed = null, Blocked = null, Filters = null };
+            Datasets datasets = new Datasets() { Allowed = null, Blocked = null, Operations = null };
+            Writes writes = new Writes() { Autofill = null };
+            cachedQueries.Allowed = new HashSet() { "my_cached_query" };
+            Options options = new Options()
+            {
+                Queries = new Core.AccessKey.Queries { Filters = qFilters },
+                CachedQueries = cachedQueries,
+                SavedQueries = savedQuaries,
+                Datasets = datasets,
+                Writes = writes
+            };
+
+            Assert.DoesNotThrow(() => client.CreateAccessKey(new AccessKey { Name = "TestAccessKey", IsActive = true, Options = options, Permitted = permissions }));
+        }
+
+    }
+}
diff --git a/Keen.NET.Test/Keen.NET.Test.csproj b/Keen.NET.Test/Keen.NET.Test.csproj
index 3f05425..f8ad2ac 100644
--- a/Keen.NET.Test/Keen.NET.Test.csproj
+++ b/Keen.NET.Test/Keen.NET.Test.csproj
@@ -99,6 +99,8 @@
     
       Properties\SharedVersionInfo.cs
     
+    
+    
     
     
     
diff --git a/Keen.NET.Test/KeenClientTest.cs b/Keen.NET.Test/KeenClientTest.cs
index 794d057..d76603f 100644
--- a/Keen.NET.Test/KeenClientTest.cs
+++ b/Keen.NET.Test/KeenClientTest.cs
@@ -1,4 +1,6 @@
 using Keen.Core;
+using Keen.Core.AccessKey;
+using Keen.Core.Query;
 using Keen.Core.EventCache;
 using Moq;
 using Newtonsoft.Json.Linq;
diff --git a/Keen/AccessKey/AccessKey.cs b/Keen/AccessKey/AccessKey.cs
new file mode 100644
index 0000000..44eb3dd
--- /dev/null
+++ b/Keen/AccessKey/AccessKey.cs
@@ -0,0 +1,83 @@
+using Keen.Core.Query;
+using System;
+using System.Collections.Generic;
+
+namespace Keen.Core.AccessKey
+{
+    /// 
+    /// Model for AccessKey object
+    /// 
+    public class AccessKey
+    {
+        public string Name { get; set; }
+        public bool IsActive { get; set; }
+        public ISet Permitted { get; set; }
+        public string Key { get; set; }
+        public Options Options { get; set; }
+    }
+
+    /// 
+    /// When SavedQueries are permitted, the Access Key will have access to run saved queries.
+    /// 
+    public class SavedQueries
+    {
+        public ISet Blocked { get; set; }
+        public IEnumerable Filters { get; set; }
+        public ISet Allowed { get; set; }
+    }
+
+    /// 
+    /// When Queries are permitted, the Access Key will have the ability to do ad-hoc queries.
+    /// 
+    public class Queries
+    {
+        public IEnumerable Filters { get; set; }
+    }
+
+    /// 
+    /// When Writes are permitted, the Access Key will have the ability to stream data to Keen.
+    /// 
+    public class Writes
+    {
+        public dynamic Autofill { get; set; } // "customer": { "id": "93iskds39kd93id", "name": "Ada Corp." }
+    }
+
+    /// 
+    /// When Datasets are permitted, the Access Key will have access to getting a dataset definition, retrieving cached dataset results, and listing cached datasets definitions for a project.
+    /// 
+    public class Datasets
+    {
+        public IEnumerable Operations { get; set; }
+        public IDictionary Allowed { get; set; }
+        public ISet Blocked { get; set; }
+    }
+
+    /// 
+    /// Optionals limiting of allowed datasets in the access key by index
+    /// 
+    public class AllowedDatasetIndexes
+    {
+        public Tuple IndexBy { get;  set;}
+    }
+
+    /// 
+    /// When CachedQueries are permitted, the Access Key will have access to retrieve results from cached queries.
+    /// 
+    public class CachedQueries
+    {
+        public ISet Blocked { get; set; }
+        public ISet Allowed { get; set; }
+    }
+
+    /// 
+    /// An object containing more details about the key’s permitted and restricted functionality.
+    /// 
+    public class Options
+    {
+        public SavedQueries SavedQueries { get; set; }
+        public Writes Writes { get; set; }
+        public Datasets Datasets { get; set; }
+        public CachedQueries CachedQueries { get; set; }
+        public Queries Queries { get; set; }
+    }
+}
diff --git a/Keen/AccessKey/AccessKeys.cs b/Keen/AccessKey/AccessKeys.cs
new file mode 100644
index 0000000..7480cc5
--- /dev/null
+++ b/Keen/AccessKey/AccessKeys.cs
@@ -0,0 +1,100 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Threading.Tasks;
+
+namespace Keen.Core.AccessKey
+{
+    /// 
+    /// AccessKeys implements the IAccessKeys interface which represents the Keen.IO Access Key API methods.
+    /// 
+    public class AccessKeys : IAccessKeys
+    {
+        private readonly IKeenHttpClient _keenHttpClient;
+        private readonly string _accesKeyRelativeUrl;
+        private readonly string _readKey;
+        private readonly string _masterKey;
+
+        internal AccessKeys(IProjectSettings prjSettings,
+                       IKeenHttpClientProvider keenHttpClientProvider)
+        {
+            if (null == prjSettings)
+            {
+                throw new ArgumentNullException(nameof(prjSettings),
+                                                "Project Settings must be provided.");
+            }
+
+            if (null == keenHttpClientProvider)
+            {
+                throw new ArgumentNullException(nameof(keenHttpClientProvider),
+                                                "A KeenHttpClient provider must be provided.");
+            }
+
+            if (string.IsNullOrWhiteSpace(prjSettings.KeenUrl) ||
+                !Uri.IsWellFormedUriString(prjSettings.KeenUrl, UriKind.Absolute))
+            {
+                throw new KeenException(
+                    "A properly formatted KeenUrl must be provided via Project Settings.");
+            }
+
+            var serverBaseUrl = new Uri(prjSettings.KeenUrl);
+            _keenHttpClient = keenHttpClientProvider.GetForUrl(serverBaseUrl);
+            _accesKeyRelativeUrl = KeenHttpClient.GetRelativeUrl(prjSettings.ProjectId,
+                                                               KeenConstants.AccessKeyResource);
+
+            _readKey = prjSettings.ReadKey;
+            _masterKey = prjSettings.MasterKey;
+        }
+
+        public async Task CreateAccessKey(AccessKey accesskey)
+        {
+            if (string.IsNullOrWhiteSpace(_masterKey))
+            {
+                throw new KeenException("An API WriteKey is required to add events.");
+            }
+            
+            DefaultContractResolver contractResolver = new DefaultContractResolver
+            {
+                NamingStrategy = new SnakeCaseNamingStrategy()
+            };
+
+            var content = JsonConvert.SerializeObject(accesskey, new JsonSerializerSettings
+            {
+                ContractResolver = contractResolver,
+                Formatting = Formatting.Indented
+            }).ToSafeString();
+
+            var responseMsg = await _keenHttpClient
+                .PostAsync(_accesKeyRelativeUrl, _masterKey, content)
+                .ConfigureAwait(continueOnCapturedContext: false);
+
+            var responseString = await responseMsg
+                .Content
+                .ReadAsStringAsync()
+                .ConfigureAwait(continueOnCapturedContext: false);
+
+            JObject jsonResponse = null;
+
+            try
+            {
+                jsonResponse = JObject.Parse(responseString);
+            }
+            catch (Exception)
+            {
+                // To avoid any flow stoppers
+            }
+            if (!responseMsg.IsSuccessStatusCode)
+            {
+                throw new KeenException("AddEvents failed with status: " + responseMsg.StatusCode);
+            }
+
+            if (null == jsonResponse)
+            {
+                throw new KeenException("AddEvents failed with empty response from server.");
+            }
+
+            return jsonResponse;
+        }
+    }
+}
diff --git a/Keen/AccessKey/IAccessKeys.cs b/Keen/AccessKey/IAccessKeys.cs
new file mode 100644
index 0000000..96bc9ea
--- /dev/null
+++ b/Keen/AccessKey/IAccessKeys.cs
@@ -0,0 +1,18 @@
+using Newtonsoft.Json.Linq;
+using System.Threading.Tasks;
+
+namespace Keen.Core.AccessKey
+{
+    /// 
+    /// Public interface for Access Key related functionalities 
+    /// 
+    public interface IAccessKeys
+    {
+        /// 
+        /// Creates an Access Key
+        /// 
+        /// 
+        /// 
+        Task CreateAccessKey(AccessKey accesskey);
+    }
+}
diff --git a/Keen/Keen.csproj b/Keen/Keen.csproj
index 5744708..b6bb48e 100644
--- a/Keen/Keen.csproj
+++ b/Keen/Keen.csproj
@@ -52,6 +52,9 @@
     
       Properties\SharedVersionInfo.cs
     
+    
+    
+    
     
     
     
diff --git a/Keen/KeenClient.cs b/Keen/KeenClient.cs
index b932e92..c4d7506 100644
--- a/Keen/KeenClient.cs
+++ b/Keen/KeenClient.cs
@@ -1,6 +1,7 @@
 using Keen.Core.DataEnrichment;
 using Keen.Core.EventCache;
 using Keen.Core.Query;
+using Keen.Core.AccessKey;
 using Newtonsoft.Json.Linq;
 using System;
 using System.Collections.Generic;
@@ -51,6 +52,12 @@ public class KeenClient
 
         public IDataset Datasets { get; set; }
 
+        /// 
+        /// AccessKeys provides direct access to the Keen.IO Access Keys API methods.
+        /// The default implementation can be overridden by setting a new implementation here.
+        /// 
+        public IAccessKeys AccessKeys { get; set; }
+
         /// 
         /// Add a static global property. This property will be added to
         /// every event.
@@ -118,8 +125,9 @@ private KeenClient(IProjectSettings prjSettings,
             // implementation via their respective properties.
             EventCollection = new EventCollection(_prjSettings, keenHttpClientProvider);
             Event = new Event(_prjSettings, keenHttpClientProvider);
-            Queries = new Queries(_prjSettings, keenHttpClientProvider);
-            Datasets = new Datasets(_prjSettings, keenHttpClientProvider);
+            Queries = new Query.Queries(_prjSettings, keenHttpClientProvider);
+            AccessKeys = new AccessKeys(_prjSettings, keenHttpClientProvider);
+            Datasets = new Dataset.Datasets(_prjSettings, keenHttpClientProvider);
         }
 
         /// 
@@ -974,8 +982,7 @@ public IEnumerable
+      
         /// Get query results from a Cached Dataset.
         /// 
         /// Name of cached dataset to query.
@@ -1146,5 +1153,32 @@ public void DeleteDataset(string datasetName)
                 throw ex.TryUnwrap();
             }
         }
+        
+        /// 
+        /// 
+        public void CreateAccessKey(AccessKey.AccessKey accessKey)
+        {
+            try
+            {
+                CreateAccessKeyAsync(accessKey).Wait();
+            }
+            catch (AggregateException ex)
+            {
+                Debug.WriteLine(ex.TryUnwrap());
+            }
+        }
+
+        ///
+        ///
+        private async Task CreateAccessKeyAsync(AccessKey.AccessKey accessKey)
+        {
+            if (null == accessKey)
+                throw new KeenException("Access Key required");
+
+            var createdKey = await AccessKeys.CreateAccessKey(accessKey)
+                .ConfigureAwait(false);
+
+            return createdKey;
+        }
     }
 }
diff --git a/Keen/KeenConstants.cs b/Keen/KeenConstants.cs
index 0b1c6a4..bb4574b 100644
--- a/Keen/KeenConstants.cs
+++ b/Keen/KeenConstants.cs
@@ -9,6 +9,9 @@ public class KeenConstants
         private const string eventsResource = "events";
         public static string EventsResource { get { return eventsResource; } protected set { ;} }
 
+        private const string accesskeyResource = "keys";
+        public static string AccessKeyResource { get { return accesskeyResource; } protected set {; } }
+
         private const string queriesResource = "queries";
         public static string QueriesResource { get { return queriesResource; } protected set { ;} }