diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Sibi Prabakaran (c) 2016
+
+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 Author name here 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/src/Network/Api/TextLocal.hs b/src/Network/Api/TextLocal.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/Api/TextLocal.hs
@@ -0,0 +1,176 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Network.Api.TextLocal
+  (Credential
+  ,createApiKey
+  ,createUserHash
+  ,SMSSettings
+  ,defaultSMSSettings
+  ,setManager
+  ,setDestinationNumber
+  ,setMessage
+  ,setAuth
+  ,runSettings
+  ,sendSMS)
+  where
+
+import Data.Text (Text)
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as B
+import Data.UnixTime (UnixTime)
+import Network.HTTP.Simple -- (setRequestManager, httpJSONEither)
+import Network.HTTP.Client (Manager, parseRequest, newManager)
+import Network.HTTP.Client.TLS (tlsManagerSettings)
+import Network.HTTP.Client.MultipartFormData (formDataBody, partBS)
+import Data.Monoid ((<>))
+import Network.Api.Types
+
+-- |
+-- Credential for making request to textLocal server.
+data Credential
+    = ApiKey ByteString
+    | UserHash ByteString -- ^ Email address
+               ByteString -- ^ Secure hash that is found within the messenger.
+
+baseUrl :: String
+baseUrl = "https://api.textlocal.in/"
+
+-- Create 'Credential' for textLocal.
+createApiKey
+    :: ByteString -- ^ api key
+    -> Credential
+createApiKey apiKey = ApiKey apiKey
+
+createUserHash :: ByteString -> ByteString -> Credential
+createUserHash email hash = UserHash email hash
+
+formCred (ApiKey apikey) = [partBS "apiKey" apikey]
+formCred (UserHash user hash) = [partBS "username" user, partBS "hash" hash]
+
+data SMSSettings = SMSSettings
+    { settingsSender :: ByteString -- ^ Sender name must be 6 alpha
+                                   -- characters and should be
+                                   -- pre-approved by Textlocal. In
+                                   -- the absence of approved sender
+                                   -- names, use the default 'TXTLCL'
+    , settingsMessage :: ByteString -- ^ The message content. This
+                                    -- parameter should be no longer
+                                    -- than 766 characters. The
+                                    -- message also must be URL
+                                    -- Encoded to support symbols like
+                                    -- &.
+    , settingsAuth :: Credential
+    , settingsNumber :: [ByteString]
+    , settingsManager :: Maybe Manager
+    , settingsGroupId :: Maybe Int
+    , settingsScheduleTime :: Maybe UnixTime
+    , settingsReceiptUrl :: Maybe ByteString
+    , settingsCustom :: Maybe Text
+    , settingsOptOut :: Maybe Bool
+    , settingsValidity :: Maybe UnixTime
+    , settingsUnicode :: Maybe Bool
+    , settingsTest :: Maybe Bool
+    }
+
+-- | 'defaultSMSSettings' has the default settings, duh! The
+-- 'settingsSender' has a value of "TXTLCL". The accessors
+-- 'settingsMessage', 'settingsAuth', 'settingsNumber' contains a
+-- value of bottom. They have to be initialized to a proper value
+-- before sending SMS.
+defaultSMSSettings =
+    SMSSettings
+    { settingsSender = "TXTLCL"
+    , settingsMessage = error "defaultSMSSettings: message content not present"
+    , settingsAuth = error "defaultSMSSettings: credential not present"
+    , settingsNumber = error "defaultSMSSettings: no number present"
+    , settingsManager = Nothing
+    , settingsGroupId = Nothing
+    , settingsScheduleTime = Nothing
+    , settingsReceiptUrl = Nothing
+    , settingsCustom = Nothing
+    , settingsOptOut = Nothing
+    , settingsValidity = Nothing
+    , settingsUnicode = Nothing
+    , settingsTest = Just False
+    }
+
+setMessage :: ByteString -> SMSSettings -> SMSSettings
+setMessage msg def =
+    def
+    { settingsMessage = msg
+    }
+
+setAuth :: Credential -> SMSSettings -> SMSSettings
+setAuth cred def =
+    def
+    { settingsAuth = cred
+    }
+
+setDestinationNumber :: [ByteString] -> SMSSettings -> SMSSettings
+setDestinationNumber num def =
+    def
+    { settingsNumber = num
+    }
+
+-- | Use an existing manager instead of creating a new one
+setManager
+    :: Manager -> SMSSettings -> SMSSettings
+setManager mgr def =
+    def
+    { settingsManager = Just mgr
+    }
+
+setTest :: Bool -> SMSSettings -> SMSSettings
+setTest test set =
+    set
+    { settingsTest = Just test
+    }
+
+sendSMS
+    :: ByteString -- ^ Text to send
+    -> [ByteString] -- ^ Destination numbers
+    -> Credential
+    -> IO (Either JSONException TLResponse)
+sendSMS msg num cred =
+    runSettings
+        SendSMS
+        defaultSMSSettings
+        { settingsAuth = cred
+        , settingsNumber = num
+        , settingsMessage = msg
+        }
+
+data Command =
+    SendSMS
+    deriving (Show,Eq,Ord)
+
+runSettings :: Command -> SMSSettings -> IO (Either JSONException TLResponse)
+runSettings cmd set = do
+    let epoint = endpointUrl cmd
+    req <- parseRequest epoint
+    mgr <- getManager (settingsManager set)
+    req' <-
+        formDataBody
+            ([ partBS "sender" (settingsSender set)
+             , partBS "message" (settingsMessage set)
+             , partBS "numbers" (B.intercalate "," $ settingsNumber set)
+             , partBS "test" (boolByteString $ settingsTest set)] <>
+             formCred (settingsAuth set))
+            req
+    let req'' = setRequestManager mgr req'
+    (response :: Response (Either JSONException TLResponse)) <-
+        httpJSONEither req''
+    return $ getResponseBody response
+
+boolByteString :: Maybe Bool -> ByteString
+boolByteString Nothing = "false"
+boolByteString (Just False) = "false"
+boolByteString (Just True) = "true"
+
+getManager :: Maybe Manager -> IO Manager
+getManager Nothing = newManager tlsManagerSettings
+getManager (Just mgr) = return mgr
+
+endpointUrl :: Command -> String
+endpointUrl SendSMS = baseUrl <> "send/"
diff --git a/src/Network/Api/Types.hs b/src/Network/Api/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/Api/Types.hs
@@ -0,0 +1,49 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Network.Api.Types where
+
+import Data.Text (Text)
+import Data.Aeson ((.:), Value(..), FromJSON(..), (.:?))
+import Control.Applicative (empty)
+
+data Error = Error
+    { ecode :: Int
+    , emessage :: Text
+    } deriving (Eq,Ord,Show)
+
+instance FromJSON Error where
+    parseJSON (Object v) = Error <$> v .: "code" <*> v .: "message"
+    parseJSON _ = empty
+
+data Warning = Warning
+    { wcode :: Int
+    , wmessage :: Text
+    } deriving (Eq,Ord,Show)
+
+instance FromJSON Warning where
+    parseJSON (Object v) = Warning <$> v .: "code" <*> v .: "message"
+    parseJSON _ = empty
+
+data TLStatus
+    = Success
+    | Failure
+    deriving (Show,Eq,Ord)
+
+instance FromJSON TLStatus where
+    parseJSON (String v) =
+        if (v == "success")
+            then return Success
+            else return Failure
+    parseJSON _ = empty
+
+data TLResponse = TLResponse
+    { status :: TLStatus
+    , warnings :: Maybe [Warning]
+    , errors :: Maybe [Error]
+    } deriving (Eq,Ord,Show)
+
+instance FromJSON TLResponse where
+    parseJSON (Object resp) =
+        TLResponse <$> resp .: "status" <*> resp .:? "warnings" <*>
+        resp .:? "errors"
+    parseJSON _ = empty
diff --git a/textlocal.cabal b/textlocal.cabal
new file mode 100644
--- /dev/null
+++ b/textlocal.cabal
@@ -0,0 +1,33 @@
+name:                textlocal
+version:             0.1.0.0
+synopsis:            Haskell wrapper for textlocal SMS gateway
+description:         Please see README.md
+homepage:            https://github.com/just-chow/textlocal
+license:             BSD3
+license-file:        LICENSE
+author:              Sibi Prabakaran
+maintainer:          sibi@psibi.in
+copyright:           2016 Sibi Prabakaran
+category:            Web
+build-type:          Simple
+bug-reports:         https://github.com/just-chow/textlocal/issues
+-- extra-source-files:
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Network.Api.Types,
+                       Network.Api.TextLocal
+  build-depends:       base >= 4.7 && < 4.9,
+                       text, 
+                       bytestring,
+                       unix-time,
+                       http-client,
+                       http-client-tls,
+                       http-conduit,
+                       aeson
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/githubuser/textlocal
