diff --git a/api-builder.cabal b/api-builder.cabal
--- a/api-builder.cabal
+++ b/api-builder.cabal
@@ -1,14 +1,24 @@
 name: api-builder
-version: 0.5.0.0
+version: 0.6.0.0
 synopsis: Library for easily building REST API wrappers in Haskell
 license: BSD3
 author: Fraser Murray
 maintainer: fraser.m.murray@gmail.com
+homepage: https://github.com/intolerable/api-builder
 copyright: (c) Fraser Murray 2014
 category: Network
 build-type: Simple
 cabal-version: >= 1.10
 
+source-repository head
+  type: git
+  location: git://github.com/intolerable/api-builder.git
+
+source-repository this
+  type: git
+  location: git://github.com/intolerable/api-builder.git
+  tag: v0.6.0.0
+
 library
   exposed-modules:
     Network.API.Builder
@@ -20,16 +30,18 @@
     Network.API.Builder.Receive
     Network.API.Builder.Routes
     Network.API.Builder.Send
+    Network.API.Builder.Send.Multipart
   build-depends:
     base >= 4.6 && < 4.8,
     aeson >= 0.7 && < 0.9,
     attoparsec >= 0.11 && < 0.13,
-    bifunctors,
+    bifunctors == 4.*,
     bytestring == 0.10.*,
     either == 4.*,
     HTTP == 4000.*,
-    http-types == 0.8.*,
+    http-client >= 0.4.7 && < 0.4.10,
     http-conduit == 2.*,
+    http-types == 0.8.*,
     text == 1.*,
     transformers >= 0.3 && < 0.5
   hs-source-dirs: src/
@@ -38,3 +50,44 @@
     FlexibleInstances
     OverloadedStrings
   ghc-options: -Wall
+
+test-suite test
+  hs-source-dirs: test
+  main-is: Spec.hs
+  default-extensions:
+    OverloadedStrings
+    ScopedTypeVariables
+  default-language: Haskell2010
+  type: exitcode-stdio-1.0
+  build-depends:
+    base == 4.*,
+    Cabal >= 1.16.0,
+    api-builder,
+    aeson,
+    bytestring,
+    datetime,
+    hspec,
+    http-conduit,
+    text,
+    transformers
+  GHC-options: -Wall -Werror
+
+test-suite test-io
+  hs-source-dirs: test-io
+  main-is: Spec.hs
+  default-extensions:
+    LambdaCase
+  default-language: Haskell2010
+  type: exitcode-stdio-1.0
+  build-depends:
+    base == 4.*,
+    Cabal >= 1.16.0,
+    api-builder,
+    aeson,
+    bytestring,
+    containers,
+    datetime,
+    hspec,
+    text,
+    transformers
+  GHC-options: -Wall -Werror
diff --git a/src/Network/API/Builder/Examples/StackOverflow.hs b/src/Network/API/Builder/Examples/StackOverflow.hs
--- a/src/Network/API/Builder/Examples/StackOverflow.hs
+++ b/src/Network/API/Builder/Examples/StackOverflow.hs
@@ -36,7 +36,7 @@
 stackOverflow = basicBuilder "StackOverflow API" "http://api.stackexchange.com"
 
 answersRoute :: Route
-answersRoute = Route { fragments = [ "2.2", "questions" ]
+answersRoute = Route { urlPieces = [ "2.2", "questions" ]
                      , urlParams = [ "order" =. ("desc" :: Text)
                                    , "sort" =. ("activity" :: Text)
                                    , "site" =. ("stackoverflow" :: Text) ]
diff --git a/src/Network/API/Builder/Query.hs b/src/Network/API/Builder/Query.hs
--- a/src/Network/API/Builder/Query.hs
+++ b/src/Network/API/Builder/Query.hs
@@ -1,5 +1,6 @@
 module Network.API.Builder.Query where
 
+import Data.Monoid
 import Data.Text (Text)
 import qualified Data.Text as Text
 
@@ -26,3 +27,12 @@
 instance ToQuery a => ToQuery [a] where
   toQuery _ [] = []
   toQuery k xs = [(k, Text.intercalate "," $ map snd $ concatMap (toQuery k) xs)]
+
+newtype IndexedList a = IndexedList [a]
+  deriving (Show, Read, Eq)
+
+instance ToQuery a => ToQuery (IndexedList a) where
+  toQuery _ (IndexedList []) = []
+  toQuery k (IndexedList l) =
+    zipWith (\n (x, y) -> (x <> "[" <> tshow n <> "]", y)) ([0..] :: [Integer]) $ concatMap (toQuery k) l
+    where tshow = Text.pack . show
diff --git a/src/Network/API/Builder/Receive.hs b/src/Network/API/Builder/Receive.hs
--- a/src/Network/API/Builder/Receive.hs
+++ b/src/Network/API/Builder/Receive.hs
@@ -2,6 +2,7 @@
 
 import Network.API.Builder.Error
 
+import Control.Applicative
 import Data.Aeson hiding (decode, eitherDecode)
 import Data.Aeson.Parser
 import Data.Aeson.Types (parseEither)
@@ -20,6 +21,18 @@
 
 instance Receivable Value where
   receive = useFromJSON
+
+instance (Receivable a, Receivable b) => Receivable (a, b) where
+  receive x = (,) <$> receive x <*> receive x
+
+instance (Receivable a, Receivable b, Receivable c) => Receivable (a, b, c) where
+  receive x = (,,) <$> receive x <*> receive x <*> receive x
+
+instance (Receivable a, Receivable b, Receivable c, Receivable d) => Receivable (a, b, c, d) where
+  receive x = (,,,) <$> receive x <*> receive x <*> receive x <*> receive x
+
+instance (Receivable a, Receivable b, Receivable c, Receivable d, Receivable e) => Receivable (a, b, c, d, e) where
+  receive x = (,,,,) <$> receive x <*> receive x <*> receive x <*> receive x <*> receive x
 
 useFromJSON :: (FromJSON a, ErrorReceivable e) => Response ByteString -> Either (APIError e) a
 useFromJSON resp =
diff --git a/src/Network/API/Builder/Routes.hs b/src/Network/API/Builder/Routes.hs
--- a/src/Network/API/Builder/Routes.hs
+++ b/src/Network/API/Builder/Routes.hs
@@ -1,6 +1,6 @@
 module Network.API.Builder.Routes
   ( Route(..)
-  , URLFragment
+  , URLPiece
   , URLParam
   , (=.)
   , routeURL ) where
@@ -15,7 +15,7 @@
 import Network.API.Builder.Query
 
 -- | Alias for @Text@ to store the URL fragments for each @Route@.
-type URLFragment = Text
+type URLPiece = Text
 
 -- | Alias to @(Text, Maybe Text)@ used to store each query that gets
 --   tacked onto the request.
@@ -34,7 +34,7 @@
 -- | Main type for routes in the API. Used to represent the URL minus the actual
 --   endpoint URL as well as the query string and the HTTP method used to communicate
 --   with the server.
-data Route = Route { fragments :: [URLFragment]
+data Route = Route { urlPieces :: [URLPiece]
                    , urlParams :: [URLParam]
                    , httpMethod :: HTTP.Method }
   deriving (Show, Read, Eq)
@@ -45,10 +45,14 @@
          -> Route -- ^ the @Route@ to process
          -> Text -- ^ the finalized URL as a @Text@
 routeURL baseURL (Route fs ps _) =
-  let path = T.intercalate "/" fs
-  in baseURL <> "/" <> path <> pathParamsSep fs <> buildParams ps
+  baseURL <> firstSep <> path <> querySep <> buildParams ps
+  where
+    firstSep = if null fs then T.empty else "/"
+    path = T.intercalate "/" fs
+    querySep = if null ps then T.empty else pathParamsSep fs
 
-pathParamsSep :: [URLFragment] -> Text
+
+pathParamsSep :: [URLPiece] -> Text
 pathParamsSep [] = "?"
 pathParamsSep xs = if T.isInfixOf "." (last xs) then "?" else "/?"
 
diff --git a/src/Network/API/Builder/Send/Multipart.hs b/src/Network/API/Builder/Send/Multipart.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/API/Builder/Send/Multipart.hs
@@ -0,0 +1,19 @@
+module Network.API.Builder.Send.Multipart where
+
+import Network.API.Builder.Builder
+import Network.API.Builder.Routes
+import Network.API.Builder.Send
+
+import Control.Monad
+import Control.Monad.IO.Class
+import Network.HTTP.Client.MultipartFormData
+import Network.HTTP.Conduit (Request)
+
+data Multipart = Multipart [Part]
+  deriving (Show)
+
+sendMultipart :: MonadIO m => Builder -> Route -> Multipart -> m (Maybe Request)
+sendMultipart b r (Multipart ps) = do
+  case send b r () of
+    Nothing -> return Nothing
+    Just req -> liftM Just $ formDataBody ps req
diff --git a/test-io/Spec.hs b/test-io/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test-io/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
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 #-}
