diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Double Crown Gaming Co. (c) 2019
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Double Crown Gaming Co. nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/servant-avro.cabal b/servant-avro.cabal
new file mode 100644
--- /dev/null
+++ b/servant-avro.cabal
@@ -0,0 +1,61 @@
+-- This file has been generated from package.yaml by hpack version 0.28.2.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: ac6c2564036b01921e8f835d5a12a73f8255e1a931734c1169ccdbfec2e1e0cf
+
+name:           servant-avro
+version:        0.1.0.0
+synopsis:       Avro content type for Servant
+description:    This package lets Servant use Avro for encoding request data
+category:       Servant, Web
+homepage:       https://github.com/doublecrowngaming/servant-avro#readme
+bug-reports:    https://github.com/doublecrowngaming/servant-avro/issues
+maintainer:     Jesse Kempf
+license:        BSD3
+license-file:   LICENSE
+build-type:     Simple
+cabal-version:  >= 1.10
+
+source-repository head
+  type: git
+  location: https://github.com/doublecrowngaming/servant-avro
+
+library
+  exposed-modules:
+      Servant.API.ContentTypes.Avro
+  other-modules:
+      Paths_servant_avro
+  hs-source-dirs:
+      src
+  default-extensions: StrictData
+  ghc-options: -Wall
+  build-depends:
+      avro
+    , base >=4.7 && <5
+    , servant
+  default-language: Haskell2010
+
+test-suite spec
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Servant.API.ContentTypes.AvroSpec
+      Paths_servant_avro
+  hs-source-dirs:
+      test
+  default-extensions: StrictData
+  ghc-options: -Wall
+  build-depends:
+      QuickCheck
+    , avro
+    , base >=4.7 && <5
+    , hspec >=2.0.0
+    , http-client
+    , servant
+    , servant-avro
+    , servant-client
+    , servant-server
+    , text
+    , warp
+  default-language: Haskell2010
diff --git a/src/Servant/API/ContentTypes/Avro.hs b/src/Servant/API/ContentTypes/Avro.hs
new file mode 100644
--- /dev/null
+++ b/src/Servant/API/ContentTypes/Avro.hs
@@ -0,0 +1,28 @@
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings     #-}
+
+module Servant.API.ContentTypes.Avro (Avro) where
+
+import           Data.Avro                (FromAvro, Result (..), ToAvro,
+                                           decode, encode)
+import           Data.Proxy               (Proxy (..))
+import           Data.Typeable            (Typeable)
+import           Servant.API.ContentTypes
+
+-- | The Avro encoding type for Servant
+data Avro
+  deriving Typeable
+
+instance Accept Avro where
+  -- The content type is given by https://avro.apache.org/docs/1.8.1/spec.html#HTTP+as+Transport
+  contentType Proxy = "avro/binary"
+
+instance ToAvro a => MimeRender Avro a where
+  mimeRender Proxy = encode
+
+instance FromAvro a => MimeUnrender Avro a where
+  mimeUnrender Proxy encoded =
+    case decode encoded of
+      Error errstr -> Left errstr
+      Success val  -> Right val
diff --git a/test/Servant/API/ContentTypes/AvroSpec.hs b/test/Servant/API/ContentTypes/AvroSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Servant/API/ContentTypes/AvroSpec.hs
@@ -0,0 +1,78 @@
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TypeOperators     #-}
+
+module Servant.API.ContentTypes.AvroSpec (spec) where
+
+import           Control.Concurrent            (forkIO)
+import           Control.Monad                 (void)
+import           Control.Monad.IO.Class        (liftIO)
+import           Data.Proxy                    (Proxy (..))
+import           Data.Text                     (Text, pack)
+import           Network.HTTP.Client           (defaultManagerSettings,
+                                                newManager)
+import qualified Network.Wai.Handler.Warp      as Warp
+import           Servant.API
+import           Servant.API.ContentTypes.Avro
+import           Servant.Client
+import           Servant.Server
+
+import           Test.Hspec
+import           Test.QuickCheck
+import           Test.QuickCheck.Monadic
+
+
+
+newtype ArbitraryText = ArbitraryText Text deriving Show
+
+instance Arbitrary ArbitraryText where
+  arbitrary = ArbitraryText . pack <$> arbitrary
+
+
+
+type TestAPI =
+  "put" :> ReqBody '[Avro, JSON] Text :> Put '[JSON] Text
+  :<|>
+  "get" :> Get '[Avro] (Maybe Text)
+
+testApp :: Application
+testApp = serve (Proxy :: Proxy TestAPI) handlers
+  where
+    handlers = handlePut :<|> handleGet
+
+    handlePut :: Text -> Handler Text
+    handlePut input = return $ input <> "x"
+
+    handleGet :: Handler (Maybe Text)
+    handleGet = return (Just "weewoo")
+
+-- The app is stateless so we don't need a fresh server each time we run a test.
+startTestApp :: IO ()
+startTestApp = void . liftIO . forkIO $ Warp.run 8888 testApp
+
+testPut :: Text -> ClientM Text
+testGet :: ClientM (Maybe Text)
+testPut :<|> testGet = client (Proxy :: Proxy TestAPI)
+
+
+spec :: Spec
+spec = do
+  runIO startTestApp
+
+  clientEnv <- runIO (mkClientEnv
+                      <$> newManager defaultManagerSettings
+                      <*> parseBaseUrl "http://localhost:8888")
+
+  describe "GET /get" $
+    it "produces the expected result" $ do
+      result <- runClientM testGet clientEnv
+      result `shouldBe` Right (Just "weewoo")
+
+  describe "PUT /put" $
+    it "appends 'x' to the request body and returns it" $ property $
+      \(ArbitraryText str) -> monadicIO $ do
+        result <- run $ runClientM (testPut str) clientEnv
+        return $ result === Right (str <> "x")
+
+  it "compiles" $
+    True `shouldBe` True
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
