diff --git a/avro.cabal b/avro.cabal
--- a/avro.cabal
+++ b/avro.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 2b77c4a4ff781ee32d8fcf7764aee0064f08ceefccd8579cfa2fc8a2d6c1ecf3
+-- hash: 86dacf38d4a96f044259ea81c7afc0a5aec901f34480f50e90d4c98b05834e43
 
 name:           avro
-version:        0.3.0.4
+version:        0.3.0.5
 synopsis:       Avro serialization support for Haskell
 description:    Avro serialization and deserialization support for Haskell
 category:       Data
@@ -24,7 +24,9 @@
     test/data/enums-object.json
     test/data/enums.avsc
     test/data/karma.avsc
+    test/data/logical.avsc
     test/data/maybe.avsc
+    test/data/record.avsc
     test/data/reused.avsc
     test/data/small.avsc
     test/data/unions-object-a.json
@@ -120,6 +122,7 @@
       Avro.NormSchemaSpec
       Avro.THEncodeContainerSpec
       Avro.THEnumSpec
+      Avro.THLogicalTypeSpec
       Avro.THReusedSpec
       Avro.THSimpleSpec
       Avro.THUnionSpec
diff --git a/src/Data/Avro/Schema.hs b/src/Data/Avro/Schema.hs
--- a/src/Data/Avro/Schema.hs
+++ b/src/Data/Avro/Schema.hs
@@ -207,30 +207,35 @@
       "bytes"   -> return Bytes
       "string"  -> return String
       somename  -> return (NamedType (TN somename))
-  parseJSON (A.Object o) =
-    do ty <- o .: ("type" :: Text)
-       case ty of
-        "map"    -> Map   <$> o .: ("values" :: Text)
-        "array"  -> Array <$> o .: ("items"  :: Text)
-        "record" ->
-          Record <$> o .:  ("name" :: Text)
-                 <*> o .:? ("namespace" :: Text)
-                 <*> o .:? ("aliases" :: Text) .!= []
-                 <*> o .:? ("doc" :: Text)
-                 <*> o .:? ("order" :: Text) .!= Just Ascending
-                 <*> o .:  ("fields" :: Text)
-        "enum"   ->
-          mkEnum <$> o .:  ("name" :: Text)
-                 <*> o .:? ("aliases" :: Text)  .!= []
-                 <*> o .:? ("namespace" :: Text)
-                 <*> o .:? ("doc" :: Text)
-                 <*> o .:  ("symbols" :: Text)
-        "fixed"  ->
-           Fixed <$> o .:  ("name" :: Text)
-                 <*> o .:? ("namespace" :: Text)
-                 <*> o .:? ("aliases" :: Text) .!= []
-                 <*> o .:  ("size" :: Text)
-        s  -> fail $ "Unrecognized object type: " <> s
+  parseJSON (A.Object o) = do
+    mbLogicalType <- o .:? ("logicalType" :: Text) :: Parser (Maybe Text)
+    ty            <- o .:  ("type" :: Text)
+
+    case mbLogicalType of
+      Just _  -> parseJSON (A.String ty)
+      Nothing ->
+        case ty of
+          "map"    -> Map   <$> o .: ("values" :: Text)
+          "array"  -> Array <$> o .: ("items"  :: Text)
+          "record" ->
+            Record <$> o .:  ("name" :: Text)
+                  <*> o .:? ("namespace" :: Text)
+                  <*> o .:? ("aliases" :: Text) .!= []
+                  <*> o .:? ("doc" :: Text)
+                  <*> o .:? ("order" :: Text) .!= Just Ascending
+                  <*> o .:  ("fields" :: Text)
+          "enum"   ->
+            mkEnum <$> o .:  ("name" :: Text)
+                  <*> o .:? ("aliases" :: Text)  .!= []
+                  <*> o .:? ("namespace" :: Text)
+                  <*> o .:? ("doc" :: Text)
+                  <*> o .:  ("symbols" :: Text)
+          "fixed"  ->
+            Fixed <$> o .:  ("name" :: Text)
+                  <*> o .:? ("namespace" :: Text)
+                  <*> o .:? ("aliases" :: Text) .!= []
+                  <*> o .:  ("size" :: Text)
+          s  -> fail $ "Unrecognized object type: " <> T.unpack s
   parseJSON (A.Array arr) | V.length arr > 0 =
            mkUnion . NE.fromList <$> mapM parseJSON (V.toList arr)
   parseJSON foo = typeMismatch "Invalid JSON for Avro Schema" foo
diff --git a/test/Avro/THLogicalTypeSpec.hs b/test/Avro/THLogicalTypeSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Avro/THLogicalTypeSpec.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+module Avro.THLogicalTypeSpec
+where
+
+import           Control.Lens
+import           Control.Monad
+
+import qualified Data.Aeson         as J
+import           Data.Aeson.Lens
+import qualified Data.ByteString    as B
+import qualified Data.Char          as Char
+import           Data.Monoid        ((<>))
+import           Data.Text          (Text)
+import qualified Data.Text          as T
+
+import           Test.Hspec
+
+import           Data.Avro
+import           Data.Avro.Deriving
+import           Data.Avro.Schema
+
+deriveAvro "test/data/logical.avsc"
+
+spec :: Spec
+spec = describe "Avro.THSpec: Logical Type Schema" $ do
+  let msgs =
+        [ Logical 12345
+        , Logical 67890
+        ]
+
+  it "should do roundtrip" $
+    forM_ msgs $ \msg ->
+      fromAvro (toAvro msg) `shouldBe` pure msg
+
+  it "should do full round trip" $
+    forM_ msgs $ \msg -> do
+      let encoded = encode msg
+      let decoded = decode encoded
+
+      decoded `shouldBe` pure msg
diff --git a/test/data/logical.avsc b/test/data/logical.avsc
new file mode 100644
--- /dev/null
+++ b/test/data/logical.avsc
@@ -0,0 +1,12 @@
+{
+  "name": "Logical",
+  "type": "record",
+  "fields": [{
+    "name": "timestamp",
+    "type":
+      {
+        "logicalType": "timestamp-millis",
+        "type": "long"
+      }
+  }]
+}
diff --git a/test/data/record.avsc b/test/data/record.avsc
new file mode 100644
--- /dev/null
+++ b/test/data/record.avsc
@@ -0,0 +1,8 @@
+{
+  "type" : "record",
+  "name" : "Thing",
+  "fields" : [ {
+    "name" : "value",
+    "type" : "int"
+  } ]
+}
