diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Revision history for bittrex
+
+## 0.1.0.0  -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2017, David Johnson
+
+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 David Johnson 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/bittrex.cabal b/bittrex.cabal
new file mode 100644
--- /dev/null
+++ b/bittrex.cabal
@@ -0,0 +1,39 @@
+name:                bittrex
+version:             0.1.0.0
+synopsis:            API bindings to bittrex.com
+description:         Haskell bindings to the Bittrex exchange
+homepage:            https://github.com/dmjio/bittrex
+license:             BSD3
+license-file:        LICENSE
+author:              David Johnson
+maintainer:          djohnson.m@gmail.com
+copyright:           David Johnson (c) 2017
+category:            Web
+build-type:          Simple
+extra-source-files:  ChangeLog.md
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Bittrex
+                       Bittrex.API
+                       Bittrex.Types
+                       Bittrex.Util
+  other-modules:       Bittrex.Internal
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+  build-depends:       aeson
+                     , base < 5
+                     , bytestring
+                     , http-client-tls
+                     , lens
+                     , lens-aeson
+                     , scientific
+                     , SHA
+                     , split
+                     , text
+                     , time
+                     , wreq
+
+source-repository head
+  type:     git
+  location: git://github.com/dmjio/bittrex.git
diff --git a/src/Bittrex.hs b/src/Bittrex.hs
new file mode 100644
--- /dev/null
+++ b/src/Bittrex.hs
@@ -0,0 +1,9 @@
+module Bittrex
+  ( module Bittrex.API
+  , module Bittrex.Types
+  , module Bittrex.Util
+  ) where
+
+import Bittrex.API
+import Bittrex.Types
+import Bittrex.Util
diff --git a/src/Bittrex/API.hs b/src/Bittrex/API.hs
new file mode 100644
--- /dev/null
+++ b/src/Bittrex/API.hs
@@ -0,0 +1,296 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE RecordWildCards     #-}
+{-# LANGUAGE DeriveGeneric       #-}
+module Bittrex.API
+  (
+    -- * Overview
+    -- $intro
+
+    -- * Public
+    getMarkets
+  , getCurrencies
+  , getTicker
+  , getMarketSummaries
+  , getMarketSummary
+  , getOrderBook
+  , getMarketHistory
+    -- * Market
+  , buyLimit
+  , sellLimit
+  , cancel
+  , getOpenOrders
+    -- * Account
+  , getBalances
+  , getBalance
+  , getDepositAddress
+  , withdraw
+  , getOrder
+  , getOrderHistory
+  , getWithdrawalHistory
+  , getDepositHistory
+  ) where
+
+import           Data.Aeson
+import           Data.Monoid
+import           Data.Text        (Text)
+import qualified Data.Text        as T
+import           Data.Scientific
+
+import           Bittrex.Types
+import           Bittrex.Util
+import           Bittrex.Internal
+
+-- $intro
+-- Bittrex provides a simple and powerful REST API to allow you to programatically perform nearly all actions you can from our web interface.
+--
+-- All requests use the application/json content type and go over https.
+-- The base url is https://bittrex.com/api/{version}/.
+--
+-- All requests are GET requests and all responses come in a default response object with the result in the result field. Always check the success flag to ensure that your API call succeeded.
+--
+-- We are currently restricting orders to 500 open orders and 200,000 orders a day. We reserve the right to change these settings as we tune the system. If you are affected by these limits as an active trader, please email support@bittrex.com.
+--
+-- If you have any questions, feedback or recommendation for API support you can post a question in our support center.
+--
+
+-- | Used to get the open and available trading markets at Bittrex along with other meta data.
+getMarkets
+  :: IO (Either ErrorMessage [Market])
+getMarkets = callAPI defOpts { path = "getmarkets" }
+
+-- | Used to get all supported currencies at Bittrex along with other meta data.
+getCurrencies
+  :: IO (Either ErrorMessage [Currency])
+getCurrencies = callAPI defOpts { path = "getcurrencies" }
+
+-- | Used to get the current tick values for a market.
+getTicker
+  :: MarketName -- ^ a string literal for the market (ex: `BTC-LTC`)
+  -> IO (Either ErrorMessage Ticker)
+getTicker market =
+  callAPI defOpts {
+      qParams = [("market", show market)]
+    , path = "getticker"
+    }
+
+-- | Used to get the last 24 hour summary of all active exchanges
+getMarketSummaries
+  :: IO (Either ErrorMessage Value)
+getMarketSummaries =
+  callAPI defOpts { path = "getmarketsummaries" }
+
+-- | Used to get the last 24 hour summary of all active exchanges
+getMarketSummary
+  :: MarketName -- ^ a string literal for the market (ex: `BTC-LTC`)
+  -> IO (Either ErrorMessage Value)
+getMarketSummary market =
+  callAPI defOpts {
+      qParams = [("market", show market)]
+    , path = "getmarketsummary"
+    }
+
+-- | Used to get retrieve the orderbook for a given market
+getOrderBook
+  :: MarketName -- ^ a string literal for the market (ex: `BTC-LTC`)
+  -> OrderBookType -- ^ buy, sell or both to identify the type of orderbook to return.
+  -> IO (Either ErrorMessage OrderBook)
+getOrderBook market orderBookType =
+  callAPI defOpts {
+      path = "getorderbook"
+    , qParams = [ ("market", show market)
+                , ("type", show orderBookType)
+                ]
+    }
+
+-- | Used to retrieve the latest trades that have occured for a specific market.
+getMarketHistory
+  :: MarketName -- ^ string literal for the market (ex: `BTC-LTC`)
+  -> IO (Either ErrorMessage [MarketHistory])
+getMarketHistory market =
+  callAPI defOpts {
+      path = "getmarkethistory"
+    , qParams = pure ("market", show market)
+    }
+
+-- | Get all orders that you currently have opened. A specific market can be requested
+getOpenOrders
+  :: APIKeys    -- ^ Bittrex API credentials
+  -> MarketName -- ^ String literal for the market (ie. BTC-LTC)
+  -> IO (Either ErrorMessage [OpenOrder])
+getOpenOrders keys market =
+  callAPI defOpts {
+      path      = "getopenorders"
+    , apiType   = MarketAPI
+    , qParams   = pure ("market", camelToDash $ show market)
+    , keys      = keys
+    }
+
+-- | Used to place a buy order in a specific market. Use buylimit to place limit orders. Make sure you have the proper permissions set on your API keys for this call to work
+buyLimit
+  :: APIKeys    -- ^ Bittrex API credentials
+  -> MarketName -- ^ A string literal for the market (ex: BTC-LTC)
+  -> Quantity   -- ^ The amount to purchase
+  -> Rate       -- ^ The rate at which to place the order.
+  -> IO (Either ErrorMessage UUID)
+buyLimit keys market quantity rate =
+  callAPI defOpts {
+      path      = "buylimit"
+    , keys      = keys
+    , apiType   = MarketAPI
+    , qParams   = [ ("market", camelToDash $ show market )
+                  , ("quantity", formatScientific Fixed Nothing quantity )
+                  , ("rate", formatScientific Fixed Nothing rate )
+                  ]
+    }
+
+-- | Used to place an sell order in a specific market. Use selllimit to place limit orders.
+-- Make sure you have the proper permissions set on your API keys for this call to workn
+sellLimit
+  :: APIKeys    -- ^ Bittrex API credentials
+  -> MarketName -- ^ A string literal for the market (ex: BTC-LTC)
+  -> Quantity   -- ^ The amount to purchase
+  -> Rate       -- ^ The rate at which to place the order
+  -> IO (Either ErrorMessage UUID)
+sellLimit keys market quantity rate =
+  callAPI defOpts {
+      path      = "selllimit"
+    , keys      = keys
+    , apiType   = MarketAPI
+    , qParams   = [ ("market", camelToDash $ show market )
+                  , ("quantity", formatScientific Fixed Nothing quantity )
+                  , ("rate", formatScientific Fixed Nothing rate )
+                  ]
+    }
+
+-- | Used to cancel a buy or sell order.
+cancel
+  :: APIKeys -- ^ Bittrex API credentials
+  -> UUID    -- ^ uuid of buy or sell order
+  -> IO (Either ErrorMessage (Maybe Text))
+cancel keys (UUID uuid) =
+  callAPI defOpts {
+      path      = "cancel"
+    , keys      = keys
+    , apiType   = MarketAPI
+    , qParams   = [ ("uuid", T.unpack uuid ) ]
+    }
+
+-- | Used to retrieve all balances from your account
+getBalances
+  :: APIKeys -- ^ Bittrex API credentials
+  -> IO (Either ErrorMessage [Balance])
+getBalances keys =
+  callAPI defOpts {
+      path    = "getbalances"
+    , keys    = keys
+    , apiType = AccountAPI
+    }
+
+-- | Used to retrieve the balance from your account for a specific currency.
+getBalance
+  :: APIKeys -- ^ Bittrex API credentials
+  -> CurrencyName -- ^ a string literal for the currency (ex: LTC)
+  -> IO (Either ErrorMessage Balance)
+getBalance keys currency =
+  callAPI defOpts {
+      path    = "getbalance"
+    , keys    = keys
+    , apiType = AccountAPI
+    , qParams = pure ("currency", T.unpack currency )
+    }
+
+-- | Used to retrieve or generate an address for a specific currency.
+-- If one does not exist, the call will fail and return ADDRESS_GENERATING until one is available.
+getDepositAddress
+  :: APIKeys -- ^ Bittrex API credentials
+  -> CurrencyName -- ^ a string literal for the currency (ie. BTC)
+  -> IO (Either ErrorMessage DepositAddress)
+getDepositAddress keys currency =
+  callAPI defOpts {
+      path    = "getdepositaddress"
+    , apiType = AccountAPI
+    , keys    = keys
+    , qParams = pure ("currency", T.unpack currency )
+    }
+
+-- | Used to retrieve your withdrawal history.
+getWithdrawalHistory
+  :: APIKeys -- ^ Bittrex API credentials
+  -> CurrencyName
+  -> IO (Either ErrorMessage [WithdrawalHistory])
+getWithdrawalHistory keys currency =
+  callAPI defOpts {
+      path    = "getwithdrawalhistory"
+    , apiType = AccountAPI
+    , keys    = keys
+    , qParams = pure ( "currency"
+                     , show currency
+                     )
+    }
+
+-- | Used to retrieve your order history.
+getOrderHistory
+  :: APIKeys -- ^ Bittrex API credentials
+  -> Maybe MarketName -- ^ a string literal for the market (ie. BTC-LTC). If ommited, will return for all markets
+  -> IO (Either ErrorMessage [OrderHistory] )
+getOrderHistory keys market =
+  callAPI defOpts {
+      path    = "getorderhistory"
+    , apiType = AccountAPI
+    , keys    = keys
+    , qParams = [ ("market", camelToDash (show m) )
+                | Just m <- pure market
+                ]
+    }
+
+-- | Used to retrieve a single order by uuid.
+getOrder
+  :: APIKeys -- ^ Bittrex API credentials
+  -> UUID    -- ^ the uuid of the buy or sell order
+  -> IO (Either ErrorMessage Order)
+getOrder keys (UUID uuid) =
+  callAPI defOpts {
+      path = "getorder"
+    , keys = keys
+    , apiType = AccountAPI
+    , qParams   = [ ("uuid", T.unpack uuid) ]
+    }
+
+-- | Used to withdraw funds from your account. note: please account for txfee.
+withdraw
+  :: APIKeys         -- ^ Bittrex API credentials
+  -> CurrencyName    -- ^ A string literal for the currency (ie. BTC)
+  -> Quantity        -- ^ The quantity of coins to withdraw
+  -> Address         -- ^ The address where to send the funds.
+  -> Maybe PaymentId -- ^ used for CryptoNotes/BitShareX/Nxt optional field (memo/paymentid)
+  -> IO (Either ErrorMessage UUID)
+withdraw keys currency quantity address payment =
+  callAPI defOpts {
+      path      = "withdraw"
+    , keys      = keys
+    , apiType   = AccountAPI
+    , qParams   = [ ("currency", T.unpack currency )
+                  , ("quantity", formatScientific Fixed Nothing quantity )
+                  , ("address", address )
+                  ] <> [ ("paymentid", show p )
+                       | Just p <- pure payment
+                       ]
+    }
+
+-- | Used to retrieve your deposit history.
+getDepositHistory
+  :: APIKeys
+  -- ^ Bittrex API credentials
+  -> Maybe CurrencyName
+  -- ^ A string literal for the currecy (ie. BTC). If `Nothing`, will return for all currencies
+  -> IO (Either ErrorMessage [DepositHistory])
+getDepositHistory keys currency =
+  callAPI defOpts {
+      path = "getdeposithistory"
+    , apiType = AccountAPI
+    , keys = keys
+    , qParams   = [ ("currency", show c)
+                  | Just c <- pure currency
+                  ]
+    }
diff --git a/src/Bittrex/Internal.hs b/src/Bittrex/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Bittrex/Internal.hs
@@ -0,0 +1,67 @@
+{-# LANGUAGE RecordWildCards   #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Bittrex.Internal where
+
+import           Control.Lens
+import           Data.Aeson
+import           Data.Aeson.Lens         (key, nth)
+import qualified Data.ByteString.Char8   as BC
+import qualified Data.ByteString.Lazy    as L
+import           Data.Char
+import           Data.Digest.Pure.SHA
+import           Data.List
+import           Data.List.Split         (splitOn)
+import           Data.Monoid
+import           Data.Time.Clock.POSIX
+import           Network.Wreq
+import           Debug.Trace
+import           Bittrex.Types
+
+-- | Default API options
+defOpts :: APIOpts
+defOpts = APIOpts PublicAPI [] "v1.1" mempty (APIKeys mempty mempty)
+
+-- | Internal, used for dispatching an API call
+callAPI
+  :: FromJSON v
+  => APIOpts
+  -> IO (Either ErrorMessage v)
+callAPI APIOpts {..} = do
+  let APIKeys {..} = keys
+  nonce <- head . splitOn "." . show <$> getPOSIXTime
+  let addAuth = apiType `elem` [AccountAPI, MarketAPI]
+      authParams = concat
+        [ [ ("apikey", apiKey) | addAuth ]
+        , [ ("nonce", nonce)   | addAuth ]
+        ]
+      addHeader o =
+          if addAuth
+            then o & header "apisign" .~ [
+               BC.pack $ showDigest $
+                 hmacSha512 (L.fromStrict (BC.pack secretKey)) $
+                   L.fromStrict (BC.pack urlForHash)
+               ]
+            else o
+      urlForHash = init $
+        mconcat [ url
+                , "?"
+                , go =<< do qParams ++ authParams
+                ]
+      go (k,v) = k <> "=" <> v <> "&"
+      url = intercalate "/" [ "https://bittrex.com/api"
+                            , version
+                            , toLower <$> show apiType
+                            , path
+                            ]
+  r <- getWith (addHeader defaults) urlForHash
+  let Just (Bool success) = r ^? responseBody . key "success"
+      Just result = r ^? responseBody . key "result"
+      Just msg = r ^? responseBody . key "message"
+  pure $ if success
+           then case fromJSON result of
+                  Error s  -> Left (DecodeFailure s result)
+                  Success m -> Right m
+           else case fromJSON msg of
+                  Success m -> Left (BittrexError m)
+                  Error s -> Left (DecodeFailure s msg)
+
diff --git a/src/Bittrex/Types.hs b/src/Bittrex/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Bittrex/Types.hs
@@ -0,0 +1,343 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE DeriveGeneric     #-}
+module Bittrex.Types where
+
+import           Data.Aeson
+import           Data.Aeson.Types
+import           Data.ByteString      (ByteString)
+import qualified Data.ByteString      as B
+import qualified Data.ByteString.Lazy as L
+import           Data.Scientific
+import           Data.Text            (Text)
+import qualified Data.Text            as T
+import           Data.Time
+import           GHC.Generics
+
+type Params = [(String,String)]
+type Rate = Scientific
+
+data APIType
+  = PublicAPI
+  | AccountAPI
+  | MarketAPI
+  deriving (Eq)
+
+instance Show APIType where
+  show AccountAPI = "account"
+  show PublicAPI  = "public"
+  show MarketAPI  = "market"
+
+data APIOpts
+  = APIOpts
+  { apiType :: APIType
+  , qParams :: Params
+  , version :: String
+  , path    :: String
+  , keys    :: APIKeys
+  } deriving (Show, Eq)
+
+data ErrorMessage
+  = BittrexError BittrexError
+  | DecodeFailure String Value
+  deriving (Show, Eq, Generic)
+
+data BittrexError
+  = INVALID_MARKET
+  | MARKET_NOT_PROVIDED
+  | APIKEY_NOT_PROVIDED
+  | APIKEY_INVALID
+  | INVALID_SIGNATURE
+  | NONCE_NOT_PROVIDED
+  | INVALID_PERMISSION
+  | INVALID_CURRENCY
+  | WITHDRAWAL_TOO_SMALL
+  | CURRENCY_DOES_NOT_EXIST
+  deriving (Show, Eq, Generic)
+
+instance FromJSON ErrorMessage
+instance FromJSON BittrexError
+
+data MarketName
+  = BTC_ADA
+  | BTC_LTC
+  deriving (Show)
+
+data Ticker = Ticker
+  { bid :: Double
+  , ask :: Double
+  , last :: Double
+  } deriving (Generic, Show)
+
+instance FromJSON Ticker where
+  parseJSON = withObject "Ticker" $ \o ->
+    Ticker <$> o .: "Bid"
+           <*> o .: "Ask"
+           <*> o .: "Last"
+
+data Market
+  = Market
+  { marketCurrency :: Text
+  , baseCurrency :: Text
+  , marketCurrencyLong :: Text
+  , baseCurrencyLong :: Text
+  , minTradeSize :: Double
+  , marketName :: Text
+  , isActive :: Bool
+  , created :: Text
+  } deriving (Show, Eq)
+
+instance FromJSON Market where
+  parseJSON = withObject "Market" $ \o ->
+    Market <$> o .: "MarketCurrency"
+           <*> o .: "BaseCurrency"
+           <*> o .: "MarketCurrencyLong"
+           <*> o .: "BaseCurrencyLong"
+           <*> o .: "MinTradeSize"
+           <*> o .: "MarketName"
+           <*> o .: "IsActive"
+           <*> o .: "Created"
+
+data Currency
+  = Currency
+  { currency :: Text
+  , currencyLong :: Text
+  , minConfirmation :: Int
+  , txFee :: Double
+  , currencyIsActive :: Bool
+  , coinType :: Text
+  , baseAddress :: Maybe Text
+  } deriving (Show, Eq)
+
+instance FromJSON Currency where
+  parseJSON = withObject "Currency" $ \o ->
+    Currency
+      <$> o .: "Currency"
+      <*> o .: "CurrencyLong"
+      <*> o .: "MinConfirmation"
+      <*> o .: "TxFee"
+      <*> o .: "IsActive"
+      <*> o .: "CoinType"
+      <*> o .: "BaseAddress"
+
+data OrderBookType
+  = Buy
+  | Sell
+  | Both
+  deriving (Show, Eq)
+
+data OrderBookEntry
+  = OrderBookEntry
+  { quantity :: Double
+  , rate :: Double
+  } deriving (Show, Eq)
+
+instance FromJSON OrderBook where
+  parseJSON = withObject "OrderBook" $ \o ->
+    OrderBook <$> o .: "buy"
+              <*> o .: "sell"
+
+data OrderBook
+  = OrderBook
+  { buy :: [OrderBookEntry]
+  , sell :: [OrderBookEntry]
+  } deriving (Show, Eq)
+
+instance FromJSON OrderBookEntry where
+  parseJSON = withObject "OrderBookEntry" $ \o ->
+    OrderBookEntry <$> o .: "Quantity"
+                   <*> o .: "Rate"
+
+k :: ByteString
+k = "{\"buy\":[{\"Quantity\":12.37000000,\"Rate\":0.02525000}],\"sell\":[{\"Quantity\":32.55412402,\"Rate\":0.02540000}]}"
+
+Right m = eitherDecode (L.fromStrict k) :: Either String OrderBook
+
+data MarketHistory
+  = MarketHistory
+  { marketHistoryId :: Integer
+  , marketHistoryTimeStamp :: Text
+  , marketHistoryQuantity :: Double
+  , marketHistoryPrice :: Double
+  , marketHistoryTotal :: Double
+  , marketHistoryFillType :: Text
+  , marketHistoryOrderType :: Text
+  } deriving (Show, Eq)
+
+instance FromJSON MarketHistory where
+  parseJSON = withObject "MarketHistory" $ \o ->
+    MarketHistory <$> o .: "Id"
+                  <*> o .: "TimeStamp"
+                  <*> o .: "Quantity"
+                  <*> o .: "Price"
+                  <*> o .: "Total"
+                  <*> o .: "FillType"
+                  <*> o .: "OrderType"
+
+type Quantity = Scientific
+type Address = String
+type PaymentId = String
+
+-- | API Keys
+data APIKeys = APIKeys
+  { apiKey :: String
+  , secretKey :: String
+  } deriving (Show, Eq)
+
+data WithdrawalHistory
+  = WithdrawalHistory
+  { whPaymentUuid :: Text
+  , whCurrency :: Text
+  , whAmount :: Scientific
+  , whAddress :: Text
+  , whOpened :: Text
+  , whAuthorized :: Bool
+  , whPendingPayment :: Bool
+  , whTxCost :: Scientific
+  , whTxId :: Text
+  , whCanceled :: Bool
+  , whInvalidAddress :: Bool
+  } deriving (Show, Eq, Generic)
+
+instance FromJSON WithdrawalHistory where
+  parseJSON = genericParseJSON defaultOptions {
+    fieldLabelModifier = drop 2
+  }
+
+data DepositHistory
+  = DepositHistory
+  { dhCurrency :: Text
+  , dhAmount :: Scientific
+  , dhLastUpdated :: Text
+  , dhConfirmations :: Scientific
+  , dhId :: Scientific
+  , dhTxId :: Text
+  , dhCryptoAddress :: Text
+  } deriving (Show, Eq, Generic)
+
+instance FromJSON DepositHistory where
+  parseJSON = genericParseJSON defaultOptions {
+    fieldLabelModifier = drop 2
+  }
+
+type CurrencyName = Text
+
+data DepositAddress
+  = DepositAddress
+  { daCurrency :: Text
+  , daAddress :: Text
+  } deriving (Show, Eq, Generic)
+
+instance FromJSON DepositAddress where
+  parseJSON = genericParseJSON defaultOptions {
+    fieldLabelModifier = drop 2
+  }
+
+newtype UUID = UUID Text
+  deriving (Show, Eq)
+
+instance FromJSON UUID where
+  parseJSON = withObject "UUID" $ \o ->
+    UUID <$> o .: "uuid"
+
+data Balance
+  = Balance
+  { bCurrency :: Text
+  , bBalance :: Scientific
+  , bAvailable :: Scientific
+  , bPending :: Scientific
+  , bCryptoAddress :: Text
+  , bUuid :: Maybe Text
+  } deriving (Show, Eq, Generic)
+
+instance FromJSON Balance where
+  parseJSON = genericParseJSON defaultOptions {
+    fieldLabelModifier = drop 1
+  }
+
+data OrderType
+  = SELL
+  | BUY
+  | LIMIT_SELL
+  | LIMIT_BUY
+  deriving (Show, Generic, Eq)
+
+instance FromJSON OrderType
+
+data OpenOrder
+  = OpenOrder
+  { ooUuid :: Maybe Text
+  , ooOrderUuid :: Text
+  , ooExchange :: Text
+  , ooOrderType :: OrderType
+  , ooQuantity :: Scientific
+  , ooQuantityRemaining :: Scientific
+  , ooLimit :: Scientific
+  , ooCommissionPaid :: Scientific
+  , ooPrice :: Scientific
+  , ooPricePerUnit :: Maybe Scientific
+  , ooOpened :: Text
+  , ooClosed :: Maybe Text
+  , ooCancelInitiated :: Bool
+  , ooImmediateOrCancel :: Bool
+  , ooIsConditional :: Bool
+  , ooCondition :: Maybe Text
+  , ooConditionTarget :: Maybe Text
+  } deriving (Show, Eq, Generic)
+
+instance FromJSON OpenOrder where
+  parseJSON = genericParseJSON defaultOptions {
+    fieldLabelModifier = drop 2
+  }
+
+data OrderHistory
+  = OrderHistory
+    { ohOrderUuid :: Text
+    , ohExchange :: Text
+    , ohTimeStamp :: Text
+    , ohOrderType :: OrderType
+    , ohLimit :: Scientific
+    , ohQuantity :: Scientific
+    , ohQuantityRemaining :: Scientific
+    , ohCommission :: Scientific
+    , ohPrice :: Scientific
+    , ohPricePerUnit :: Maybe Scientific
+    , ohIsConditional :: Bool
+    , ohImmediateOrCancel :: Bool
+    } deriving (Show, Eq, Generic)
+
+instance FromJSON OrderHistory where
+  parseJSON = genericParseJSON defaultOptions {
+    fieldLabelModifier = drop 2
+  }
+
+data Order
+  = Order
+    { oAccountId :: Maybe Text
+    , oOrderUuid :: Text
+    , oExchange :: Text
+    , oOrderType :: OrderType
+    , oQuantity :: Scientific
+    , oQuantityRemaining :: Scientific
+    , oLimit :: Scientific
+    , oReserved :: Scientific
+    , oReservedRemaining :: Scientific
+    , oCommissionReserved :: Scientific
+    , oCommissionReserveRemaining :: Scientific
+    , oCommissionPaid :: Scientific
+    , oPrice :: Scientific
+    , oPricePerUnit :: Maybe Scientific
+    , oOpen :: Text
+    , oIsOpen :: Bool
+    , oSentinal :: Text
+    , oTimeStamp :: Text
+    , oCommission :: Scientific
+    , oIsConditional :: Bool
+    , oImmediateOrCancel :: Bool
+    , oCancelInitiated :: Bool
+    , oCondition :: Text
+    } deriving (Show, Eq, Generic)
+
+instance FromJSON Order where
+  parseJSON = genericParseJSON defaultOptions {
+    fieldLabelModifier = drop 1
+  }
diff --git a/src/Bittrex/Util.hs b/src/Bittrex/Util.hs
new file mode 100644
--- /dev/null
+++ b/src/Bittrex/Util.hs
@@ -0,0 +1,6 @@
+module Bittrex.Util ( camelToDash ) where
+
+camelToDash :: String -> String
+camelToDash [] = []
+camelToDash ('_':xs) = '-':camelToDash xs
+camelToDash (x:xs) = x:camelToDash xs
