diff --git a/lib/diplomat/kv.rb b/lib/diplomat/kv.rb
index cd982d5..0cee5dd 100644
--- a/lib/diplomat/kv.rb
+++ b/lib/diplomat/kv.rb
@@ -1,7 +1,7 @@
 module Diplomat
   # Methods for interacting with the Consul KV API endpoint
   class Kv < Diplomat::RestClient
-    @access_methods = %i[get put delete txn]
+    @access_methods = %i[get get_attributes put delete txn]
     attr_reader :key, :value, :raw
 
     # Get a value by its key, potentially blocking for the first or next value
@@ -50,6 +50,7 @@ def get(key, options = {}, not_found = :reject, found = :return)
       custom_params << dc(@options)
       custom_params << keys(@options)
       custom_params << separator(@options)
+      custom_params << session(@options)
 
       return_nil_values = @options && @options[:nil_values]
       transformation = @options && @options[:transformation] && @options[:transformation].methods.find_index(:call) ? @options[:transformation] : nil
@@ -97,6 +98,20 @@ def get(key, options = {}, not_found = :reject, found = :return)
     end
     # rubocop:enable PerceivedComplexity, LineLength, CyclomaticComplexity
 
+    # Get key attributes
+    # @param key [String] the key
+    # @param options [Hash] the query params
+    # @return [OpenStruct]
+    def get_attributes(key, options = {})
+      @options = options
+      custom_params = []
+      custom_params << use_cas(@options)
+      custom_params << dc(@options)
+      custom_params << session(@options)
+      @raw = send_get_request(@conn, ["/v1/kv/#{key}"], options, custom_params)
+      OpenStruct.new JSON.parse(@raw.body).first
+    end
+
     # Associate a value with a key
     # @param key [String] the key
     # @param value [String] the value
@@ -111,6 +126,7 @@ def put(key, value, options = {})
       custom_params << use_cas(@options)
       custom_params << dc(@options)
       custom_params << acquire(@options)
+      custom_params << session(@options)
       @raw = send_put_request(@conn, ["/v1/kv/#{key}"], options, value, custom_params)
       if @raw.body.chomp == 'true'
         @key = key
@@ -131,6 +147,7 @@ def delete(key, options = {})
       custom_params = []
       custom_params << recurse_get(@options)
       custom_params << dc(@options)
+      custom_params << session(@options)
       @raw = send_delete_request(@conn, ["/v1/kv/#{@key}"], options, custom_params)
     end
 
@@ -162,6 +179,7 @@ def txn(value, options = {})
       custom_params = []
       custom_params << dc(options)
       custom_params << transaction_consistency(options)
+      custom_params << session(options)
       raw = send_put_request(@conn_no_err, ['/v1/txn'], options, value, custom_params)
       transaction_return JSON.parse(raw.body), options
     end
@@ -188,6 +206,10 @@ def separator(options)
       options[:separator] ? use_named_parameter('separator', options[:separator]) : []
     end
 
+    def session(options)
+      options[:session] ? use_named_parameter('session', options[:session]) : []
+    end
+
     def transaction_consistency(options)
       return [] unless options
 
diff --git a/spec/kv_spec.rb b/spec/kv_spec.rb
index f23337f..6f50ce8 100644
--- a/spec/kv_spec.rb
+++ b/spec/kv_spec.rb
@@ -356,6 +356,32 @@
       end
     end
 
+    describe '#get attributes' do
+      context 'of a key' do
+        let(:json) do
+          JSON.generate(
+            [
+              {
+                "LockIndex": 1,
+                "Key": 'foo',
+                "Flags": 0,
+                "Value": 'InRvdG8i',
+                "CreateIndex": 630,
+                "ModifyIndex": 630
+              }
+            ]
+          )
+        end
+
+        it 'return attributes' do
+          kv = Diplomat::Kv.new
+          stub_request(:get, 'http://localhost:8500/v1/kv/foo')
+            .to_return(OpenStruct.new(status: 200, body: json))
+          kv.get_attributes('foo')
+        end
+      end
+    end
+
     describe '#put' do
       context 'ACLs NOT enabled' do
         it 'PUT' do