diff --git a/features/ClientSpec.hs b/features/ClientSpec.hs
new file mode 100644
--- /dev/null
+++ b/features/ClientSpec.hs
@@ -0,0 +1,21 @@
+module ClientSpec
+  ( spec
+  ) where
+
+import           Data.Either    (isLeft)
+import           Grakn
+import           Servant.Client (BaseUrl (BaseUrl), Scheme (Http))
+import           Test.Hspec
+
+spec :: Spec
+spec =
+  describe
+    "As a Grakn Developer I should be able to connect to a running Grakn Instance and use that instance to issue queries." $
+  it "Issuing a query with a broken connection" $ do
+    let client = aBrokenConnectionToTheDatabase
+    result <- execute client "match $x sub entitty"
+    result `shouldSatisfy` isLeft
+
+aBrokenConnectionToTheDatabase :: Client
+aBrokenConnectionToTheDatabase =
+  Client (BaseUrl Http "1.2.3.4" 5678 "") "akeyspace"
diff --git a/features/Env.hs b/features/Env.hs
new file mode 100644
--- /dev/null
+++ b/features/Env.hs
@@ -0,0 +1,42 @@
+module Env where
+
+import           Data.String.Utils (rstrip)
+import           System.Exit       (ExitCode (ExitSuccess))
+import           System.Process    (CreateProcess, createProcess, proc,
+                                    readCreateProcess, waitForProcess)
+
+env :: [String] -> CreateProcess
+env = proc "features/grakn-spec/env.sh"
+
+envStart :: IO Bool
+envStart = envSuccess ["start", "1.0.0"]
+
+envStop :: IO ()
+envStop = do
+  _ <- envSuccess ["stop"]
+  return ()
+
+envKeyspace :: IO String
+envKeyspace = rstrip <$> readCreateProcess (env ["keyspace"]) ""
+
+envInsert :: String -> IO ()
+envInsert patterns = do
+  _ <- envSuccess ["insert", patterns]
+  return ()
+
+envDefine :: String -> IO ()
+envDefine patterns = do
+  _ <- envSuccess ["define", patterns]
+  return ()
+
+envCheckType :: String -> IO Bool
+envCheckType label = envSuccess ["check", "type", label]
+
+envCheckInstance :: String -> String -> IO Bool
+envCheckInstance res value = envSuccess ["check", "instance", res, value]
+
+envSuccess :: [String] -> IO Bool
+envSuccess args = do
+    (_, _, _, p) <- createProcess $ env args
+    code <- waitForProcess p
+    return $ code == ExitSuccess
diff --git a/features/GraqlQuerySpec.hs b/features/GraqlQuerySpec.hs
new file mode 100644
--- /dev/null
+++ b/features/GraqlQuerySpec.hs
@@ -0,0 +1,117 @@
+module GraqlQuerySpec
+  ( spec
+  ) where
+
+import           Control.Exception (Exception, displayException)
+import           Data.Either       (isLeft)
+import           Data.Map          (member)
+import           Data.Text         (pack)
+import           Env
+import           Grakn
+import           Test.Hspec
+
+aKnowledgeBaseContainingTypesAndInstances :: IO Client
+aKnowledgeBaseContainingTypesAndInstances = do
+  client <- givenAKnowledgeBase
+  envDefine "person sub entity, has name; name sub attribute, datatype string;"
+  envInsert "$alice isa person, has name \"Alice\";"
+  return client
+
+givenAKnowledgeBase :: IO Client
+givenAKnowledgeBase = Client defaultUrl <$> envKeyspace
+
+x :: Var
+x = var $ pack "x"
+
+spec :: Spec
+spec =
+  before aKnowledgeBaseContainingTypesAndInstances $
+  describe
+    "As a Grakn Developer, I should be able to interact with a Grakn knowledge base using Graql queries" $ do
+    it "Valid Define Query" $ \client -> do
+      response <- execute client "define $x label dog sub entity;"
+      typeIsInTheKB "dog"
+      response `hasVar` x
+    it "Redundant Define Query" $ \client -> do
+      response <- execute client "define $x label person sub entity;"
+      response `hasVar` x
+    it "Valid Insert Query" $ \client -> do
+      response <- execute client "insert $bob isa person, has name \"Bob\";"
+      instanceIsInTheKB "name" "Bob"
+      response `hasAnswers` 1
+    it "Invalid Insert Query" $ \client -> do
+      response <-
+        execute client "insert $dunstan isa dog, has name \"Dunstan\";"
+      isAnError response
+    it "Get Query With Empty Response" $ \client -> do
+      response <- execute client "match $x isa person, has name \"Precy\"; get;"
+      response `hasAnswers` 0
+    it "Get Query With Non-Empty Response" $ \client -> do
+      response <- execute client "match $x isa person, has name \"Alice\"; get;"
+      response `hasAnswers` 1
+    it "Aggregate Ask Query With False Response" $ \client -> do
+      response <- execute client "match $x has name \"Precy\"; aggregate ask;"
+      response `is` AskResult False
+    it "Aggregate Ask Query With True Response" $ \client -> do
+      response <- execute client "match $x has name \"Alice\"; aggregate ask;"
+      response `is` AskResult True
+    it "Aggregate Query" $ \client -> do
+      response <- execute client "match $x isa person; aggregate count;"
+      response `is` CountResult 1
+    it "Compute Query" $ \client -> do
+      response <- execute client "compute count in person;"
+      response `is` CountResult 1
+    it "Successful Undefine Query" $ \client -> do
+      envDefine "dog sub entity;"
+      response <- execute client "undefine dog sub entity;"
+      response `is` DeleteResult
+    it "Unsuccessful Undefine Query" $ \client -> do
+      response <- execute client "undefine person sub entity;"
+      isAnError response
+    it "Delete Query for non Existent Concept" $ \client -> do
+      response <- execute client "match $x has name \"Precy\"; delete $x;"
+      response `is` DeleteResult
+    it "Inference on by default" $ \client -> do
+      envDefine
+        "weird-rule sub rule when { $person has name \"Alice\"; } then { $person has name \"A\"; };"
+      response <- execute client "match $x has name \"A\"; get;"
+      response `hasAnswers` 1
+    it "Inference can be disabled" $ \client -> do
+      envDefine
+        "weird-rule sub rule when { $person has name \"Alice\"; } then { $person has name \"A\"; };"
+      response <-
+        execute_ Options {infer = False} client "match $x has name \"A\"; get;"
+      response `hasAnswers` 0
+
+is :: (Exception e, Show a, Eq a) => Either e a -> a -> Expectation
+response `is` expected =
+  case response of
+    Right answer -> answer `shouldBe` expected
+    Left err     -> expectationFailure (displayException err)
+
+isAnError :: Either t a -> Expectation
+isAnError response = isLeft response `shouldBe` True
+
+typeIsInTheKB :: String -> Expectation
+typeIsInTheKB label = do
+  isIn <- envCheckType label
+  isIn `shouldBe` True
+
+instanceIsInTheKB :: String -> String -> Expectation
+instanceIsInTheKB res val = do
+  isIn <- envCheckInstance res val
+  isIn `shouldBe` True
+
+hasAnswers :: Exception e => Either e Result -> Int -> Expectation
+response `hasAnswers` n =
+  case response of
+    Right (AnswersResult answers) -> length answers `shouldBe` n
+    Left err -> expectationFailure (displayException err)
+    x -> expectationFailure (show x)
+
+hasVar :: Exception e => Either e Result -> Var -> Expectation
+response `hasVar` var =
+  case response of
+    Right (AnswerResult answer) -> member var answer `shouldBe` True
+    Left err                    -> expectationFailure (displayException err)
+    x                           -> expectationFailure (show x)
diff --git a/features/Spec.hs b/features/Spec.hs
new file mode 100644
--- /dev/null
+++ b/features/Spec.hs
@@ -0,0 +1,2 @@
+{-# OPTIONS_GHC
+  -F -pgmF hspec-discover -optF --module-name=Spec #-}
diff --git a/grakn.cabal b/grakn.cabal
--- a/grakn.cabal
+++ b/grakn.cabal
@@ -1,7 +1,7 @@
 name:                 grakn
-version:              0.2.0
-synopsis:             A Haskell client for <http://grakn.ai Grakn>
-description:          A Haskell client for <http://grakn.ai Grakn>
+version:              0.3.0
+synopsis:             A Haskell client for Grakn
+description:          See README.md
 license:              Apache-2.0
 license-file:         LICENSE
 homepage:             https://github.com/graknlabs/grakn-haskell
@@ -24,7 +24,7 @@
                       , scientific  == 0.3.*
                       , text        == 1.2.*
                       , regex-posix == 0.95.*
-                      , servant     == 0.9.*
+                      , servant     >= 0.9
                       , servant-client
                       , http-client
                       , mtl
@@ -52,11 +52,11 @@
                       , grakn
                       , containers  == 0.5.*
                       , process     == 1.4.*
-                      , aeson       == 1.0.*
+                      , aeson       == 1.*
                       , scientific  == 0.3.*
                       , text        == 1.2.*
                       , regex-posix == 0.95.*
-                      , servant     == 0.9.*
+                      , servant     >= 0.9
                       , servant-client
                       , http-client
                       , mtl
@@ -66,6 +66,14 @@
                       , markdown-unlit
                       , MissingH
   other-modules:        Example
+                      , Grakn
+                      , GraknSpec
+                      , Grakn.Client
+                      , Grakn.ClientSpec
+                      , Grakn.Pattern
+                      , Grakn.Property
+                      , Grakn.Query
+                      , Grakn.Util
   default-language:     Haskell2010
   ghc-options:          -pgmL markdown-unlit
   default-extensions:   MultiParamTypeClasses
@@ -82,11 +90,11 @@
                       , grakn
                       , containers  == 0.5.*
                       , process     == 1.4.*
-                      , aeson       == 1.0.*
+                      , aeson       == 1.*
                       , scientific  == 0.3.*
                       , text        == 1.2.*
                       , regex-posix == 0.95.*
-                      , servant     == 0.9.*
+                      , servant     >= 0.9
                       , servant-client
                       , http-client
                       , mtl
@@ -94,6 +102,16 @@
                       , hspec
                       , markdown-unlit
                       , MissingH
+  other-modules:        ClientSpec
+                      , Env
+                      , Spec
+                      , GraqlQuerySpec
+                      , Grakn
+                      , Grakn.Client
+                      , Grakn.Pattern
+                      , Grakn.Property
+                      , Grakn.Query
+                      , Grakn.Util
   default-language:     Haskell2010
   default-extensions:   MultiParamTypeClasses
                       , FlexibleInstances
diff --git a/src/Grakn.hs b/src/Grakn.hs
--- a/src/Grakn.hs
+++ b/src/Grakn.hs
@@ -1,21 +1,23 @@
 module Grakn
-  ( MatchQuery
-  , Graph(Graph, keyspace, url)
+  ( Match
+  , GetQuery
+  , Client(Client, keyspace, url)
   , GraknError
-  , Result(MatchResult, InsertResult, AskResult, CountResult,
+  , Result(AnswersResult, AnswerResult, AskResult, CountResult,
        DeleteResult)
+  , Options(Options, infer)
   , Var
-  , Name
-  , Value(..)
+  , Label
+  , Value(ValueString, ValueNumber, ValueBool)
   , defaultUrl
   , defaultKeyspace
   , execute
+  , execute_
   , match
-  , select
-  , distinct
+  , get
   , limit
   , var
-  , name
+  , label
   , isa
   , (-:)
   , (.:)
@@ -28,15 +30,19 @@
   ) where
 
 import           Data.Text      (Text)
-import           Grakn.Client   (GraknError, Graph (Graph, keyspace, url), Result (AskResult, CountResult, DeleteResult, InsertResult, MatchResult),
-                                 defaultKeyspace, defaultUrl, execute)
-import           Grakn.Pattern
-import           Grakn.Property
-import           Grakn.Query
+import           Grakn.Client   (Client (Client, keyspace, url), GraknError,
+                                 Options (Options, infer),
+                                 Result (AnswerResult, AnswersResult, AskResult, CountResult, DeleteResult),
+                                 defaultKeyspace, defaultUrl, execute, execute_)
+import           Grakn.Pattern  (Pattern, has, isa, var_, (<:))
+import           Grakn.Property (Label, RolePlayer,
+                                 Value (ValueBool, ValueNumber, ValueString),
+                                 Var, VarOrLabel, label, rp, var, (.:))
+import           Grakn.Query    (GetQuery, Match, get, limit, match)
 import           Grakn.Util     (Convert)
 
 -- |Specify a property has a particular type
-(-:) :: (Convert p Pattern, Convert a VarOrName) => p -> a -> Pattern
+(-:) :: (Convert p Pattern, Convert a VarOrLabel) => p -> a -> Pattern
 (-:) = isa
 
 -- |Shorthand to define a relation
@@ -44,5 +50,5 @@
 rel = (var_ <:)
 
 -- |Specify a property has a resource
-hasText :: (Convert p Pattern) => p -> Name -> Text -> Pattern
+hasText :: (Convert p Pattern) => p -> Label -> Text -> Pattern
 hasText = has
diff --git a/src/Grakn/Client.hs b/src/Grakn/Client.hs
--- a/src/Grakn/Client.hs
+++ b/src/Grakn/Client.hs
@@ -1,33 +1,36 @@
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards   #-}
 
 module Grakn.Client
-  ( Graph(Graph, keyspace, url)
-  , Concept(Concept, cid, cname, ctype, value)
+  ( Client(Client, keyspace, url)
+  , Concept(Concept, cid, clabel, ctype, value)
   , GraknError
-  , Result(MatchResult, InsertResult, AskResult, CountResult,
+  , Result(AnswersResult, AnswerResult, AskResult, CountResult,
        DeleteResult)
+  , Options(Options, infer)
   , defaultUrl
   , defaultKeyspace
   , execute
+  , execute_
   ) where
 
-import           Control.Applicative      (empty)
-import           Data.Aeson               (FromJSON, ToJSON, encode, parseJSON,
-                                           (.:), (.:?))
-import qualified Data.Aeson               as Aeson
-import           Data.Foldable            (asum)
-import           Data.Map                 (Map)
-import           Data.Proxy               (Proxy (Proxy))
-import           Data.Text                (Text)
-import           Grakn.Property           (Name, Value, Var)
-import           Grakn.Query              (IsQuery (queryString))
-import           Network.HTTP.Client      (defaultManagerSettings, newManager)
-import           Network.HTTP.Media       ((//))
-import           Servant.API
-import           Servant.API.ContentTypes (eitherDecodeLenient)
-import           Servant.Client
+import           Data.Aeson          (FromJSON, Object, parseJSON, withObject,
+                                      (.:), (.:?))
+import           Data.Aeson.Types    (Parser)
+import           Data.Foldable       (asum)
+import           Data.Map            (Map)
+import           Data.Proxy          (Proxy (Proxy))
+import           Data.Text           (Text)
+import           Grakn.Property      (Label, Value, Var)
+import           Grakn.Query         (IsQuery (queryString))
+import           Network.HTTP.Client (defaultManagerSettings, newManager)
+import           Servant.API         ((:>), Capture, JSON, PlainText, Post,
+                                      QueryParam, ReqBody)
+import           Servant.Client      (BaseUrl (BaseUrl), ClientEnv (ClientEnv),
+                                      ClientM, Scheme (Http), ServantError,
+                                      client, runClientM)
 
-data Graph = Graph
+data Client = Client
   { url      :: BaseUrl
   , keyspace :: String
   }
@@ -36,21 +39,21 @@
   GraknError String
   deriving (Eq, Show)
 
--- |A result of a match query, binding variables to concepts
+-- |A result of a query
 data Result
-  = MatchResult [Map Var Concept]
-  | InsertResult [Text]
+  = AnswersResult [Map Var Concept]
+  | AnswerResult (Map Var Concept)
+  | DeleteResult
   | AskResult Bool
   | CountResult Integer
-  | DeleteResult
   deriving (Show, Eq)
 
--- |A concept in the graph
+-- |A concept in the knowledge base
 data Concept = Concept
-  { cid   :: Text
-  , cname :: Maybe Name
-  , ctype :: Maybe Name
-  , value :: Maybe Value
+  { cid    :: Text
+  , clabel :: Maybe Label
+  , ctype  :: Maybe Label
+  , value  :: Maybe Value
   } deriving (Show, Eq)
 
 -- |The default Grakn URL, accessing localhost
@@ -61,55 +64,59 @@
 defaultKeyspace :: String
 defaultKeyspace = "grakn"
 
-execute :: IsQuery q => Graph -> q -> IO (Either ServantError Result)
-execute (Graph u ks) query = do
+data Options = Options
+  { infer :: Bool
+  }
+
+type ExecuteResponse = IO (Either ServantError Result)
+
+execute :: IsQuery q => Client -> q -> ExecuteResponse
+execute = executeOpts Nothing
+
+execute_ :: IsQuery q => Options -> Client -> q -> ExecuteResponse
+execute_ opts = executeOpts (Just opts)
+
+executeOpts :: IsQuery q => Maybe Options -> Client -> q -> ExecuteResponse
+executeOpts opts (Client u ks) query = do
   manager <- newManager defaultManagerSettings
   let env = ClientEnv manager u
-  runClientM (graqlGet (queryString query) ks) env
-
-type Keyspace = QueryParam "keyspace" String
+  runClientM (graqlGet opts (queryString query) ks) env
 
 type Infer = QueryParam "infer" Bool
 
-type Materialise = QueryParam "materialise" Bool
-
-type Body = ReqBody '[ PlainText] String
+type Query = ReqBody '[ PlainText] String
 
-type GraknParams
-   = Keyspace :> Infer :> Materialise :> Body :> Post '[ GraqlJSON] Result
+type Keyspace = Capture "keyspace" String
 
 -- |A type describing the REST API we use to execute queries
-type GraknAPI = "graph" :> "graql" :> "execute" :> GraknParams
+type GraknAPI
+   = "kb" :> Keyspace :> "graql" :> Infer :> Query :> Post '[ JSON] Result
 
 graknAPI :: Proxy GraknAPI
 graknAPI = Proxy
 
-graqlGet :: String -> String -> ClientM Result
-graqlGet query ks = client graknAPI (Just ks) (Just False) (Just False) query
+graqlGet :: Maybe Options -> String -> String -> ClientM Result
+graqlGet opts query ks = client graknAPI ks (infer <$> opts) query
 
+-- This is a helper method for chaining accessing optional JSON fields
+(.:>) :: FromJSON a => Parser (Maybe Object) -> Text -> Parser (Maybe a)
+maybeParser .:> key = traverse (.: key) =<< maybeParser
+
 instance FromJSON Concept where
-  parseJSON (Aeson.Object obj) =
-    Concept <$> (obj .: "id") <*> (obj .:? "name") <*> (obj .:? "isa") <*>
-    (obj .:? "value")
-  parseJSON _ = empty
+  parseJSON =
+    withObject "Concept" $ \obj -> do
+      cid <- obj .: "id"
+      clabel <- obj .:? "label"
+      ctype <- obj .:? "type" .:> "label"
+      value <- obj .:? "value"
+      return Concept {..}
 
 instance FromJSON Result where
   parseJSON val =
     asum
-      [ MatchResult <$> parseJSON val
-      , InsertResult <$> parseJSON val
+      [ AnswersResult <$> parseJSON val
+      , AnswerResult <$> parseJSON val
       , AskResult <$> parseJSON val
       , CountResult <$> parseJSON val
       , pure DeleteResult
       ]
-
-data GraqlJSON
-
-instance Accept GraqlJSON where
-  contentType _ = "application" // "graql+json"
-
-instance ToJSON a => MimeRender GraqlJSON a where
-  mimeRender _ = encode
-
-instance FromJSON a => MimeUnrender GraqlJSON a where
-  mimeUnrender _ = eitherDecodeLenient
diff --git a/src/Grakn/Pattern.hs b/src/Grakn/Pattern.hs
--- a/src/Grakn/Pattern.hs
+++ b/src/Grakn/Pattern.hs
@@ -6,12 +6,13 @@
   , has
   ) where
 
-import           Grakn.Property
+import           Grakn.Property (Label, Property (Has, Isa, Rel), RolePlayer,
+                                 Value, Var, VarOrLabel)
 import           Grakn.Util     (Convert (convert), spaces, with)
 
--- |A pattern to find in the graph
+-- |A pattern to find in the knowledge base
 data Pattern =
-  Pattern (Maybe VarOrName)
+  Pattern (Maybe VarOrLabel)
           [Property]
 
 -- |Create an anonymous variable
@@ -19,7 +20,7 @@
 var_ = Pattern Nothing []
 
 -- |Specify a property has a particular type
-isa :: (Convert p Pattern, Convert a VarOrName) => p -> a -> Pattern
+isa :: (Convert p Pattern, Convert a VarOrLabel) => p -> a -> Pattern
 patt `isa` x = addProperty patt (Isa $ convert x)
 
 -- |Specify a property is a relation between other variables
@@ -30,7 +31,7 @@
 has ::
      (Convert p Pattern, Convert a (Either Value Var))
   => p
-  -> Name
+  -> Label
   -> a
   -> Pattern
 has patt rt v = addProperty patt (Has rt $ convert v)
@@ -49,10 +50,10 @@
   show (Pattern v props) = v `with` " " ++ showProps props ++ ";"
 
 instance Convert Var Pattern where
-  convert = convert . (convert :: Var -> VarOrName)
+  convert = convert . (convert :: Var -> VarOrLabel)
 
-instance Convert Name Pattern where
-  convert = convert . (convert :: Name -> VarOrName)
+instance Convert Label Pattern where
+  convert = convert . (convert :: Label -> VarOrLabel)
 
-instance Convert VarOrName Pattern where
+instance Convert VarOrLabel Pattern where
   convert v = Pattern (Just v) []
diff --git a/src/Grakn/Property.hs b/src/Grakn/Property.hs
--- a/src/Grakn/Property.hs
+++ b/src/Grakn/Property.hs
@@ -1,12 +1,12 @@
 module Grakn.Property
-  ( Property(..)
+  ( Property(Isa, Has, Rel)
   , RolePlayer
   , Var
-  , Name
-  , VarOrName
-  , Value(..)
+  , Label
+  , VarOrLabel
+  , Value(ValueString, ValueNumber, ValueBool)
   , var
-  , name
+  , label
   , (.:)
   , rp
   ) where
@@ -23,26 +23,26 @@
 
 -- |A property of a concept
 data Property
-  = Isa VarOrName
-  | NameProperty Name
+  = Isa VarOrLabel
+  | LabelProperty Label
   | Rel [RolePlayer]
-  | Has Name
+  | Has Label
         (Either Value Var)
 
--- |A variable name wildcard that will represent a concept in the results
+-- |A variable that will represent a concept in the results
 newtype Var =
   Var Text
   deriving (Eq, Ord)
 
--- |A name of something in the graph
-newtype Name =
-  Name Text
+-- |A label of something in the knowledge base
+newtype Label =
+  Label Text
   deriving (Eq)
 
--- |Something that may be a variable name or a type name
-data VarOrName
+-- |Something that may be a variable or a type label
+data VarOrLabel
   = VarName Var
-  | TypeName Name
+  | TypeLabel Label
 
 -- |A value of a resource
 data Value
@@ -53,33 +53,33 @@
 
 -- |A casting, relating a role type and role player
 data RolePlayer =
-  RolePlayer (Maybe VarOrName)
+  RolePlayer (Maybe VarOrLabel)
              Var
 
 -- |Create a variable
 var :: Text -> Var
 var = Var
 
--- |Create a name of something in the graph
-name :: Text -> Name
-name = Name
+-- |Create a label of something in the knowledge base
+label :: Text -> Label
+label = Label
 
 -- |A casting in a relation between a role type and a role player
-(.:) :: Convert a VarOrName => a -> Var -> RolePlayer
+(.:) :: Convert a VarOrLabel => a -> Var -> RolePlayer
 rt .: player = RolePlayer (Just $ convert rt) player
 
 -- |A casting in a relation without a role type
 rp :: Var -> RolePlayer
 rp = RolePlayer Nothing
 
-nameRegex :: String
-nameRegex = "^[a-zA-Z_][a-zA-Z0-9_-]*$"
+labelRegex :: String
+labelRegex = "^[a-zA-Z_][a-zA-Z0-9_-]*$"
 
 instance Show Property where
-  show (Isa varOrName)  = "isa " ++ show varOrName
-  show (NameProperty n) = "type-name " ++ show n
-  show (Rel castings)   = "(" ++ commas castings ++ ")"
-  show (Has rt value)   = "has " ++ show rt ++ " " ++ showEither value
+  show (Isa varOrLabel)  = "isa " ++ show varOrLabel
+  show (LabelProperty n) = "label " ++ show n
+  show (Rel castings)    = "(" ++ commas castings ++ ")"
+  show (Has rt value)    = "has " ++ show rt ++ " " ++ showEither value
 
 instance Show RolePlayer where
   show (RolePlayer roletype player) = roletype `with` ": " ++ show player
@@ -89,9 +89,9 @@
   show (ValueNumber num)  = show num
   show (ValueBool bool)   = show bool
 
-instance Show Name where
-  show (Name text)
-    | str =~ nameRegex = str
+instance Show Label where
+  show (Label text)
+    | str =~ labelRegex = str
     | otherwise = show text
     where
       str = unpack text
@@ -99,15 +99,15 @@
 instance Show Var where
   show (Var v) = '$' : unpack v
 
-instance Show VarOrName where
-  show (VarName v)  = show v
-  show (TypeName t) = show t
+instance Show VarOrLabel where
+  show (VarName v)   = show v
+  show (TypeLabel t) = show t
 
-instance Convert Var VarOrName where
+instance Convert Var VarOrLabel where
   convert = VarName
 
-instance Convert Name VarOrName where
-  convert = TypeName
+instance Convert Label VarOrLabel where
+  convert = TypeLabel
 
 instance Convert Var RolePlayer where
   convert = rp
@@ -130,8 +130,8 @@
   parseJSON (Aeson.Bool b)   = return $ ValueBool b
   parseJSON _                = empty
 
-instance FromJSON Name where
-  parseJSON (Aeson.String s) = return $ name s
+instance FromJSON Label where
+  parseJSON (Aeson.String s) = return $ label s
   parseJSON _                = empty
 
 instance FromJSON Var where
diff --git a/src/Grakn/Query.hs b/src/Grakn/Query.hs
--- a/src/Grakn/Query.hs
+++ b/src/Grakn/Query.hs
@@ -1,51 +1,50 @@
 module Grakn.Query
   ( IsQuery(queryString)
-  , MatchQuery
+  , Match
+  , GetQuery
   , match
-  , select
+  , get
   , limit
-  , distinct
   ) where
 
-import           Grakn.Pattern
-import           Grakn.Property
-import           Grakn.Util
+import           Grakn.Pattern  (Pattern)
+import           Grakn.Property (Var)
+import           Grakn.Util     (Convert, commas, convert, spaces)
 
 class IsQuery q where
   queryString :: q -> String
 
--- |A Graql 'match' query that finds a pattern in the graph
-data MatchQuery
+-- |A Graql 'match' part that finds a pattern in the knowledge base
+data Match
   = Match [Pattern]
-  | Select MatchQuery
-           [Var]
-  | Limit MatchQuery
+  | Limit Match
           Integer
-  | Distinct MatchQuery
 
--- |Create a match query by providing a list of patterns
-match :: Convert a Pattern => [a] -> MatchQuery
+data GetQuery =
+  GetQuery Match
+           [Var]
+
+-- |Create a match by providing a list of patterns
+match :: Convert a Pattern => [a] -> Match
 match = Match . map convert
 
--- |Select variables from a match query, intended to be used infix
-select :: [Var] -> MatchQuery -> MatchQuery
-select = flip Select
+-- |Get variables from a match, intended to be used infix
+get :: [Var] -> Match -> GetQuery
+get = flip GetQuery
 
--- |Limit a match query, intended to be used infix
-limit :: Integer -> MatchQuery -> MatchQuery
+-- |Limit a match, intended to be used infix
+limit :: Integer -> Match -> Match
 limit = flip Limit
 
--- |Retrieve only distinct results from a match query
-distinct :: MatchQuery -> MatchQuery
-distinct = Distinct
+instance Show Match where
+  show (Match patts)  = "match " ++ spaces patts
+  show (Limit mq lim) = show mq ++ " limit " ++ show lim ++ ";"
 
-instance Show MatchQuery where
-  show (Match patts)    = "match " ++ spaces patts
-  show (Select mq vars) = show mq ++ " select " ++ commas vars ++ ";"
-  show (Limit mq lim)   = show mq ++ " limit " ++ show lim ++ ";"
-  show (Distinct mq)    = show mq ++ " distinct;"
+instance Show GetQuery where
+  show (GetQuery match_ [])   = show match_ ++ " get;"
+  show (GetQuery match_ vars) = show match_ ++ " get " ++ commas vars ++ ";"
 
-instance IsQuery MatchQuery where
+instance IsQuery GetQuery where
   queryString = show
 
 instance IsQuery String where
diff --git a/test/Example.lhs b/test/Example.lhs
--- a/test/Example.lhs
+++ b/test/Example.lhs
@@ -2,7 +2,7 @@
 
 A Haskell client for [Grakn](http://grakn.ai).
 
-Requires Grakn 0.16.
+Requires Grakn 1.0.0.
 
 # Installation
 
@@ -30,20 +30,20 @@
 import Data.Function ((&))
 ```
 
-Define the type names:
+Define the type labels:
 
 ```haskell
-person :: Name
-person = name "person"
+person :: Label
+person = label "person"
 
-husband :: Name
-husband = name "husband"
+husband :: Label
+husband = label "husband"
 
-wife :: Name
-wife = name "wife"
+wife :: Label
+wife = label "wife"
 
-marriage :: Name
-marriage = name "marriage"
+marriage :: Label
+marriage = label "marriage"
 ```
 
 Define the variables:
@@ -59,35 +59,35 @@
 We can translate the following query into Haskell:
 
 ```graql
-match $x isa person, (husband: $x, wife: $y) isa marriage; select $y;
+match $x isa person, (husband: $x, wife: $y) isa marriage; get $y;
 ```
 
 ```haskell
-query :: MatchQuery
+query :: GetQuery
 query = match
     [ x `isa` person
     , rel [husband .: x, wife .: y] `isa` marriage
-    ] & select [y]
+    ] & get [y]
 ```
 
 We can also use infix functions like `(-:)` instead of `isa`:
 
 ```haskell
-otherQuery :: MatchQuery
+otherQuery :: GetQuery
 otherQuery = match
     [ x -: person
     , rel [husband .: x, wife .: y] -: marriage
-    ] & select [y]
+    ] & get [y]
 ```
 
 To execute and print the results of our query:
 
 ```haskell
-graph :: Graph
-graph = Graph defaultUrl "my-keyspace"
+client :: Client
+client = Client defaultUrl "my-keyspace"
 
 main :: IO ()
 main = do
-    result <- execute graph query
+    result <- execute client query
     print result
 ```
diff --git a/test/Grakn/ClientSpec.hs b/test/Grakn/ClientSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Grakn/ClientSpec.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Grakn.ClientSpec
+  ( spec
+  ) where
+
+import           Data.Aeson      (decode)
+import           Grakn           (Value (ValueNumber), label)
+import           Grakn.Client
+import qualified Servant.Client  as S
+import           Test.Hspec
+import           Test.QuickCheck (Arbitrary, arbitrary, elements, property)
+
+spec :: Spec
+spec = do
+  it "The client's keyspace is set correctly" $
+    property $ \(BaseUrl u) k ->
+      let client = Client {url = u, keyspace = k}
+      in keyspace client `shouldBe` k
+  it "The client's URI is set correctly" $
+    property $ \(BaseUrl u) k ->
+      let client = Client {url = u, keyspace = k}
+      in url client `shouldBe` u
+  it "type can be parsed from JSON" $ do
+    let person = Just (label "person")
+    let json = "{\"id\": \"V123\", \"label\": \"person\"}"
+    let concept =
+          Concept
+          {cid = "V123", clabel = person, ctype = Nothing, value = Nothing}
+    decode json `shouldBe` Just concept
+  it "instance can be parsed from JSON" $ do
+    let number = Just (label "number")
+    let val = Just (ValueNumber 3)
+    let json =
+          "{\"id\": \"V123\", \"type\": {\"label\": \"number\"}, \"value\": 3}"
+    let concept =
+          Concept {cid = "V123", clabel = Nothing, ctype = number, value = val}
+    decode json `shouldBe` Just concept
+
+newtype BaseUrl =
+  BaseUrl S.BaseUrl
+  deriving (Show)
+
+instance Arbitrary BaseUrl where
+  arbitrary = do
+    let scheme = elements [S.Http, S.Https]
+    BaseUrl <$> (S.BaseUrl <$> scheme <*> arbitrary <*> arbitrary <*> arbitrary)
diff --git a/test/GraknSpec.hs b/test/GraknSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/GraknSpec.hs
@@ -0,0 +1,70 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module GraknSpec
+  ( spec
+  ) where
+
+import           Data.Function ((&))
+import qualified Example
+import           Grakn
+import           Test.Hspec
+
+spec :: Spec
+spec = do
+  it "a simple query string representation" $
+    match [x `isa` person] & get [] ~= "match $x isa person; get;"
+  it "a relation query string representation" $
+    match [rel [x, y]] & get [] ~= "match ($x, $y); get;"
+  it "a relation query string representation with types" $
+    match [rel [husband .: x, wife .: y] -: marriage] & get [] ~=
+    "match (husband: $x, wife: $y) isa marriage; get;"
+  it "a resource query string representation" $
+    match [x `hasText` firstName $ "Bob"] & get [] ~=
+    "match $x has first-name \"Bob\"; get;"
+  it "multiple patterns" $
+    match [x -: person, y -: firstName] & get [] ~=
+    "match $x isa person; $y isa first-name; get;"
+  it "get query with type" $
+    match [x -: y] & get [x, y] ~= "match $x isa $y; get $x, $y;"
+  it "mix role types" $
+    match [rel [husband .: x, rp y]] & get [] ~= "match (husband: $x, $y); get;"
+  it "limit" $
+    match [x -: person] & limit 10 & get [] ~=
+    "match $x isa person; limit 10; get;"
+  it "type of type" $
+    match [person -: x] & get [] ~= "match person isa $x; get;"
+  it "reify a relation" $
+    match [x <: [y, z]] & get [] ~= "match $x ($y, $z); get;"
+  it "match just a variable" $ match [x] & get [] ~= "match $x; get;"
+  it "example query output" $
+    Example.query ~=
+    "match $x isa person; (husband: $x, wife: $y) isa marriage; get $y;"
+
+x :: Var
+x = var "x"
+
+y :: Var
+y = var "y"
+
+z :: Var
+z = var "z"
+
+person :: Label
+person = label "person"
+
+firstName :: Label
+firstName = label "first-name"
+
+marriage :: Label
+marriage = label "marriage"
+
+husband :: Label
+husband = label "husband"
+
+wife :: Label
+wife = label "wife"
+
+infixr 0 ~=
+
+(~=) :: GetQuery -> String -> Expectation
+(~=) = shouldBe . show
