diff --git a/consul/server.go b/consul/server.go
index d873cd2b9b..598e6bde3e 100644
--- a/consul/server.go
+++ b/consul/server.go
@@ -108,6 +108,7 @@ type endpoints struct {
 	Raft     *Raft
 	Status   *Status
 	KVS      *KVS
+	Session  *Session
 	Internal *Internal
 }
 
@@ -316,6 +317,7 @@ func (s *Server) setupRPC(tlsConfig *tls.Config) error {
 	s.endpoints.Catalog = &Catalog{s}
 	s.endpoints.Health = &Health{s}
 	s.endpoints.KVS = &KVS{s}
+	s.endpoints.Session = &Session{s}
 	s.endpoints.Internal = &Internal{s}
 
 	// Register the handlers
@@ -324,6 +326,7 @@ func (s *Server) setupRPC(tlsConfig *tls.Config) error {
 	s.rpcServer.Register(s.endpoints.Catalog)
 	s.rpcServer.Register(s.endpoints.Health)
 	s.rpcServer.Register(s.endpoints.KVS)
+	s.rpcServer.Register(s.endpoints.Session)
 	s.rpcServer.Register(s.endpoints.Internal)
 
 	list, err := net.ListenTCP("tcp", s.config.RPCAddr)
diff --git a/consul/session_endpoint.go b/consul/session_endpoint.go
new file mode 100644
index 0000000000..79938fc182
--- /dev/null
+++ b/consul/session_endpoint.go
@@ -0,0 +1,106 @@
+package consul
+
+import (
+	"fmt"
+	"github.com/armon/go-metrics"
+	"github.com/hashicorp/consul/consul/structs"
+	"time"
+)
+
+// Session endpoint is used to manipulate sessions for KV
+type Session struct {
+	srv *Server
+}
+
+// Apply is used to apply a modifying request to the data store. This should
+// only be used for operations that modify the data
+func (s *Session) Apply(args *structs.SessionRequest, reply *string) error {
+	if done, err := s.srv.forward("Session.Apply", args, args, reply); done {
+		return err
+	}
+	defer metrics.MeasureSince([]string{"consul", "session", "apply"}, time.Now())
+
+	// Verify the args
+	if args.Session.ID == "" && args.Op == structs.SessionDestroy {
+		return fmt.Errorf("Must provide ID")
+	}
+	if args.Session.Node == "" && args.Op == structs.SessionCreate {
+		return fmt.Errorf("Must provide Node")
+	}
+
+	// Apply the update
+	resp, err := s.srv.raftApply(structs.SessionRequestType, args)
+	if err != nil {
+		s.srv.logger.Printf("[ERR] consul.session: Apply failed: %v", err)
+		return err
+	}
+	if respErr, ok := resp.(error); ok {
+		return respErr
+	}
+
+	// Check if the return type is a string
+	if respString, ok := resp.(string); ok {
+		*reply = respString
+	}
+	return nil
+}
+
+// Get is used to retrieve a single session
+func (s *Session) Get(args *structs.SessionGetRequest,
+	reply *structs.IndexedSessions) error {
+	if done, err := s.srv.forward("Session.Get", args, args, reply); done {
+		return err
+	}
+
+	// Get the local state
+	state := s.srv.fsm.State()
+	return s.srv.blockingRPC(&args.QueryOptions,
+		&reply.QueryMeta,
+		state.QueryTables("SessionGet"),
+		func() error {
+			index, session, err := state.SessionGet(args.Session)
+			reply.Index = index
+			if session != nil {
+				reply.Sessions = structs.Sessions{session}
+			}
+			return err
+		})
+}
+
+// List is used to list all the active sessions
+func (s *Session) List(args *structs.DCSpecificRequest,
+	reply *structs.IndexedSessions) error {
+	if done, err := s.srv.forward("Session.List", args, args, reply); done {
+		return err
+	}
+
+	// Get the local state
+	state := s.srv.fsm.State()
+	return s.srv.blockingRPC(&args.QueryOptions,
+		&reply.QueryMeta,
+		state.QueryTables("SessionList"),
+		func() error {
+			var err error
+			reply.Index, reply.Sessions, err = state.SessionList()
+			return err
+		})
+}
+
+// NodeSessions is used to get all the sessions for a particular node
+func (s *Session) NodeSessions(args *structs.NodeSpecificRequest,
+	reply *structs.IndexedSessions) error {
+	if done, err := s.srv.forward("Session.NodeSessions", args, args, reply); done {
+		return err
+	}
+
+	// Get the local state
+	state := s.srv.fsm.State()
+	return s.srv.blockingRPC(&args.QueryOptions,
+		&reply.QueryMeta,
+		state.QueryTables("NodeSessions"),
+		func() error {
+			var err error
+			reply.Index, reply.Sessions, err = state.NodeSessions(args.Node)
+			return err
+		})
+}
diff --git a/consul/structs/structs.go b/consul/structs/structs.go
index 10c423b036..d2e5aba24e 100644
--- a/consul/structs/structs.go
+++ b/consul/structs/structs.go
@@ -348,6 +348,7 @@ type Session struct {
 	Checks      []string
 	CreateIndex uint64
 }
+type Sessions []*Session
 
 type SessionOp string
 
@@ -368,6 +369,22 @@ func (r *SessionRequest) RequestDatacenter() string {
 	return r.Datacenter
 }
 
+// SessionGetRequest is used to request a session by ID
+type SessionGetRequest struct {
+	Datacenter string
+	Session    string
+	QueryOptions
+}
+
+func (r *SessionGetRequest) RequestDatacenter() string {
+	return r.Datacenter
+}
+
+type IndexedSessions struct {
+	Sessions Sessions
+	QueryMeta
+}
+
 // Decode is used to decode a MsgPack encoded object
 func Decode(buf []byte, out interface{}) error {
 	var handle codec.MsgpackHandle