diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -2,8 +2,10 @@
 
 `tyro` is a dependently type JSON parsing library, that provides a quick way to create JSON parsers by deriving them from a type level description of the position of the value to be obtained.
 
-## Example
+## Examples
 
+### Type driven interface
+
 ```Haskell
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE DataKinds #-}
@@ -11,14 +13,26 @@
 
 import Data.Tyro
 import Data.Aeson (decode)
-import Data.Text (Text)
+import qualified Data.ByteString.Lazy as B
 
-json = "{\"key1\":[{\"key2\":41},{\"key2\":42}]}" :: Text
+json = "{\"key1\":[{\"key2\":41},{\"key2\":42}]}" :: B.ByteString
 
 -- Extract [41, 42] inside the Tyro types
-parsed = decode json :: Maybe ("key1" |>| List ("key2" |>| Parse Integer))
+parsed = decode json :: Maybe ("key1" >%> List ("key2" >%> Extract Integer))
 
 -- We can dispose of the types using unwrap
 values :: Maybe [Integer]
 values = fmap unwrap parsed
+```
+
+### Value driven interface
+
+```Haskell
+{-# LANGUAGE OverloadedStrings #-}
+import Data.Tyro
+
+json = "{\"key1\": {\"key2\" :  [41, 42]}}" :: B.ByteString
+
+-- Extract [41, 42] inside the JSON
+parsed = json %%> "key1" >%> "key2" >%> extract :: Maybe [Integer]
 ```
diff --git a/src/Data/Tyro.hs b/src/Data/Tyro.hs
--- a/src/Data/Tyro.hs
+++ b/src/Data/Tyro.hs
@@ -12,14 +12,22 @@
 {-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
 module Data.Tyro (
   -- * Introduction
-  -- $example
+  -- $introduction
 
   -- * Building types
-  Parse
-, type( |>| )
+  -- $typed_example
+  Extract
+, type( >%> )
 , List
 , unwrap
 
+-- * Value level API
+-- $value_example
+, Tyro
+, extract
+, (>%>)
+, (%%>)
+
 -- * Internal types
 , JSBranch ) where
 
@@ -27,6 +35,8 @@
 import           Data.Aeson ((.:))
 import qualified Data.Aeson as A
 import           Data.Aeson.Types (Parser)
+import qualified Data.ByteString.Lazy as B
+import           Data.Reflection (reifySymbol)
 import           Data.Singletons (Sing, SingI(..))
 import           Data.Singletons.Prelude.List (Sing(SNil, SCons))
 import           Data.Singletons.TypeLits ( Symbol, SSymbol, KnownSymbol
@@ -37,47 +47,73 @@
 import           Lib.Prelude
 
 
--- $example
--- A small (artificial) example demonstrating how to use the types defined here.
---
--- > {-# LANGUAGE OverloadedStrings #-}
--- > {-# LANGUAGE DataKinds #-}
--- > {-# LANGUAGE TypeOperators #-}
--- > import Data.Tyro
--- > import Data.Aeson (decode)
--- > import Data.Text (Text)
--- >
--- > json = "{\"key1\":[{\"key2\":41},{\"key2\":42}]}" :: Text
--- >
--- > -- Extract [41, 42] inside the Tyro types
--- > parsed = decode json :: Maybe ("key1" |>| List ("key2" |>| Parse Integer))
--- >
--- > -- We can dispose of the types using unwrap: 'values' will have the value
--- > -- Just [41, 42]
--- > values :: Maybe [Integer]
--- > values = fmap unwrap parsed
 
-
-
 --------------------------------------------------------------------------------
 -- Type level API using a type family to mirror JSON structure
 --------------------------------------------------------------------------------
 
--- | @Parse a@ represents trying to parse JSON to an @a@.
-type Parse a = JSBranch '[] a
+-- | @Extract a@ represents trying to parse JSON to an @a@.
+type Extract a = JSBranch '[] a
 
--- | The type operator '|>|' provides a way of describing how to walk
+-- | The type operator '>%> provides a way of describing how to walk
 -- down a JSON tree.
-type family (x :: Symbol) |>| (b :: *) :: *
-type instance (x :: Symbol) |>| JSBranch xs a = JSBranch (x ': xs) a
+type family (x :: Symbol) >%> (b :: *) :: *
+type instance (x :: Symbol) >%> JSBranch xs a = JSBranch (x ': xs) a
 
 -- | The 'List' type operator constructs a parsing type for parsing
 -- a list of JSON objects.
 type family List (x :: *) :: *
-type instance List (JSBranch xs a) = Parse [JSBranch xs a]
+type instance List (JSBranch xs a) = Extract [JSBranch xs a]
 
 
+
 --------------------------------------------------------------------------------
+-- Value level API using reification
+--------------------------------------------------------------------------------
+
+-- | 'Tyro' is an abstract type representing a parser that walks down a JSON
+-- tree.
+newtype Tyro = Tyro [String] deriving (Eq, Show)
+
+-- | 'extract' is the value which represents halting the walk along the JSON
+-- tree, and pulling out the value there.
+extract :: Tyro
+extract = Tyro []
+
+
+-- | '>%>' allows you to specify a subtree indexed by a key. It's right
+-- associative, so chains of keys can be specified without parenthesese.
+(>%>) :: String -> Tyro -> Tyro
+(>%>) s (Tyro t) = Tyro (s:t)
+infixr 9 >%>
+
+
+-- | Internal proxying datatype for accumulating reified values as a list
+data TyroProxy :: [Symbol] -> * where
+  Take :: TyroProxy '[]
+  Key :: TyroProxy s -> TyroProxy (t ': s)
+
+
+-- | '%%>' tries to parse a ByteString along a 'Tyro' to obtain a value
+(%%>) :: (A.FromJSON a) => B.ByteString -> Tyro -> Maybe a
+(%%>) bs (Tyro xs) = go bs (reverse xs) Take
+  where
+    go :: (A.FromJSON a, SingI xs) =>
+      B.ByteString -> [String] -> TyroProxy xs -> Maybe a
+    go b [] t = fmap unwrap $ parse b t
+    go b (k:ks) t = reifySymbol k $ \p -> go b ks (extend t p)
+
+    parse :: (A.FromJSON a, SingI xs) =>
+      B.ByteString -> TyroProxy xs -> Maybe (JSBranch xs a)
+    parse b _ = A.decode b
+
+    extend :: (KnownSymbol s) => TyroProxy xs -> Proxy s -> TyroProxy (s ': xs)
+    extend t _ = Key t
+infixl 8 %%>
+
+
+
+--------------------------------------------------------------------------------
 -- Basic dependent structure
 --------------------------------------------------------------------------------
 
@@ -98,22 +134,66 @@
 
 instance (A.FromJSON a, SingI xs) => A.FromJSON (JSBranch xs a) where
   parseJSON :: (A.FromJSON a, SingI xs) => A.Value -> Parser (JSBranch xs a)
-  parseJSON = parseSing sing
+  parseJSON = parse sing
     where
-      parseSing :: (A.FromJSON a) => Sing xs -> A.Value -> Parser (JSBranch xs a)
-      parseSing s o = case s of
+      parse :: (A.FromJSON a) => Sing xs -> A.Value -> Parser (JSBranch xs a)
+      parse s o = case s of
         SNil -> JSNil <$> A.parseJSON o
         x `SCons` xs -> case o of
-          A.Object v -> let key = pack (reflectSym x) in
-            JSCons <$> (v .: key >>= parseSing xs)
+          A.Object v -> let key = pack (reflectSymbol x) in
+            JSCons <$> (v .: key >>= parse xs)
           _ -> empty
 
 
 -- | 'reflectSym' reflects a type level symbol into a value level string
-reflectSym :: SSymbol s -> String
-reflectSym s = withKnownSymbol s $ proxySym s Proxy
+reflectSymbol :: SSymbol s -> String
+reflectSymbol s = withKnownSymbol s $ proxySym s Proxy
   where
     proxySym :: (KnownSymbol n) => SSymbol n -> Proxy n -> String
     proxySym _ = symbolVal
 
 
+
+--------------------------------------------------------------------------------
+-- Documentation
+--------------------------------------------------------------------------------
+
+-- $introduction
+-- 'Tyro' provides a type driven way of obtaining simple JSON parsers, and
+-- a simple value driven interface to obtain values deep inside a JSON object.
+
+-- $typed_example
+-- A small (artificial) example demonstrating how to use the typed interface.
+--
+-- > {-# LANGUAGE OverloadedStrings #-}
+-- > {-# LANGUAGE DataKinds #-}
+-- > {-# LANGUAGE TypeOperators #-}
+-- > import Data.Tyro
+-- > import Data.Aeson (decode)
+-- > import qualified Data.ByteString.Lazy as B
+-- >
+-- > json = "{\"key1\":[{\"key2\":41},{\"key2\":42}]}" :: B.ByteString
+-- >
+-- > -- Extract [41, 42] inside the Tyro types
+-- > parsed = decode json :: Maybe ("key1" >%> List ("key2" >%> Extract Integer))
+-- >
+-- > -- We can dispose of the types using unwrap: 'values' will have the value
+-- > -- Just [41, 42]
+-- > values :: Maybe [Integer]
+-- > values = fmap unwrap parsed
+
+
+-- $value_example
+-- The value level interface allows a piece of the JSON object to be extracted
+-- in a similar way to most dynamically typed languages.
+--
+-- > {-# LANGUAGE OverloadedStrings #-}
+-- > import Data.Tyro
+-- >
+-- > json = "{\"key1\": {\"key2\" :  [41, 42]}}" :: B.ByteString
+-- >
+-- > -- Extract [41, 42] inside the JSON
+-- > parsed = json %%> "key1" >%> "key2" >%> extract :: Maybe [Integer]
+--
+-- Not the overloaded strings extension in the above is only used to define
+-- the 'json' 'ByteString'..
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -16,19 +16,25 @@
 main = defaultMain tests
 
 tests :: [ TF.Test ]
-tests = [ genericJSONParserTests ]
+tests = [ typeLevelJSONParserTests
+        , valueLevelJSONParserTests ]
 
 
-genericJSONParserTests :: TF.Test
-genericJSONParserTests = testGroup "\nGeneric JSON Parser tests" . hUnitTestToTests $
+typeLevelJSONParserTests :: TF.Test
+typeLevelJSONParserTests = testGroup "\nType level JSON Parser tests" . hUnitTestToTests $
   HU.TestList [ canExtractTextInJSBranch
               , canExtractIntegerInJSBranch
               , canExtractListInJSBranch
               , canExtractListInJSBranchWithTypeFamily ]
 
+valueLevelJSONParserTests :: TF.Test
+valueLevelJSONParserTests = testGroup "Value leve JSON Parser tests" . hUnitTestToTests $
+  HU.TestList [ canUseValueLevelKeysToParseInteger
+              , canUseValueLevelKeysToExtractList
+              , canUseOperatorsWithoutBrackets ]
 
 --------------------------------------------------------------------------------
--- Generic JSON Parser tests
+-- Type level JSON Parser tests
 --------------------------------------------------------------------------------
 
 canExtractTextInJSBranch :: HU.Test
@@ -60,6 +66,42 @@
 canExtractListInJSBranchWithTypeFamily = "Can extract JSBranch on List with type family" ~:
   let json = "{\"key1\":[{\"key2\":41},{\"key2\":42}]}"
       expected = Just [41,42]
-      decoded = A.decode json :: Maybe ("key1" |>| List ("key2" |>| Parse Integer))
+      decoded = A.decode json :: Maybe ("key1" >%> List ("key2" >%> Extract Integer))
   in
     expected @=? (fmap (fmap unwrap) . (fmap unwrap) $ decoded)
+
+
+--------------------------------------------------------------------------------
+-- Value level parsing tests
+--------------------------------------------------------------------------------
+
+canUseValueLevelKeysToParseInteger :: HU.Test
+canUseValueLevelKeysToParseInteger =
+  "Can extract integer using value level API" ~:
+  let json = "{\"key1\":{\"key2\":{\"key3\":42}}}"
+      parser = "key1" >%> "key2" >%> "key3" >%> extract
+      expected = Just 42
+      decoded = json %%> parser :: Maybe Integer
+  in
+    expected @=? decoded
+
+
+canUseValueLevelKeysToExtractList :: HU.Test
+canUseValueLevelKeysToExtractList =
+  "Can extract list of integers using value level API" ~:
+  let json = "{\"key1\": {\"key2\" :  [41, 42]}}"
+      parser = "key1" >%> "key2" >%> extract
+      expected = Just [41,42]
+      decoded = json %%> parser :: Maybe [Integer]
+  in
+    expected @=? decoded
+
+
+canUseOperatorsWithoutBrackets :: HU.Test
+canUseOperatorsWithoutBrackets =
+  "Can use operators without brackets in mainline case" ~:
+  let json = "{\"key1\": {\"key2\" :  [41, 42]}}"
+      expected = Just [41,42]
+      decoded = json %%> "key1" >%> "key2" >%> extract :: Maybe [Integer]
+  in
+    expected @=? decoded
diff --git a/tyro.cabal b/tyro.cabal
--- a/tyro.cabal
+++ b/tyro.cabal
@@ -1,5 +1,5 @@
 name:                tyro
-version:             0.1.1.1
+version:             0.2.0.0
 synopsis:            Type derived JSON parsing using Aeson
 description:
     A library for deriving JSON parsers (using Aeson) by indicating
@@ -24,7 +24,9 @@
                      , protolude >= 0.1.6 && < 0.2
                      , aeson
                      , text
+                     , bytestring
                      , singletons
+                     , reflection
   default-language:    Haskell2010
   default-extensions:  OverloadedStrings, NoImplicitPrelude
 
