diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
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/aws-lambda.cabal b/aws-lambda.cabal
new file mode 100644
--- /dev/null
+++ b/aws-lambda.cabal
@@ -0,0 +1,50 @@
+name:                aws-lambda
+version:             0.1.0.0
+synopsis:            Haskell bindings for AWS Lambda
+license:             Apache-2.0
+license-file:        LICENSE
+author:              Jon Sterling
+maintainer:          jon@jonmsterling.com
+copyright:           Copyright (c) 2013-2014 PivotCloud, Inc.
+category:            Network, Cloud
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Aws.Lambda,
+                       Aws.Lambda.Core,
+                       Aws.Lambda.Types,
+                       Aws.Lambda.Commands.AddEventSource,
+                       Aws.Lambda.Commands.DeleteFunction,
+                       Aws.Lambda.Commands.GetEventSource,
+                       Aws.Lambda.Commands.GetFunction,
+                       Aws.Lambda.Commands.GetFunctionConfiguration,
+                       Aws.Lambda.Commands.InvokeAsync,
+                       Aws.Lambda.Commands.ListEventSources,
+                       Aws.Lambda.Commands.ListFunctions,
+                       Aws.Lambda.Commands.RemoveEventSource,
+                       Aws.Lambda.Commands.UpdateFunctionConfiguration,
+                       Aws.Lambda.Commands.UploadFunction,
+                       Aws.Lambda.Internal.Constraints
+  other-modules:       Aws.Lambda.Internal.Utils
+  build-depends:       base >=4.7 && <4.8,
+                       base-unicode-symbols,
+                       aeson >=0.8.0.2,
+                       aws-general >=0.1,
+                       bytestring >= 0.10.4.0,
+                       containers >= 0.5.5.1,
+                       exceptions >= 0.6.1,
+                       filepath >= 1.3.0.2,
+                       http-types >=0.8.5,
+                       http-client >=0.4.6,
+                       lens >=4.6 && <4.7,
+                       lens-aeson >=1.0.0.3,
+                       mtl >=2.1.3.1,
+                       old-locale >=1.0.0.6,
+                       text >=1.2.0.0,
+                       time >=1.4.2,
+                       wreq >=0.3.0.1,
+                       zip-archive >=0.2.3.5
+  hs-source-dirs:      src
+  ghc-options:         -Wall
+  default-language:    Haskell2010
diff --git a/src/Aws/Lambda.hs b/src/Aws/Lambda.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda.hs
@@ -0,0 +1,49 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+module Aws.Lambda
+( module Aws.Lambda.Core
+, module Aws.Lambda.Types
+, module Aws.Lambda.Commands.AddEventSource
+, module Aws.Lambda.Commands.DeleteFunction
+, module Aws.Lambda.Commands.GetEventSource
+, module Aws.Lambda.Commands.GetFunction
+, module Aws.Lambda.Commands.GetFunctionConfiguration
+, module Aws.Lambda.Commands.InvokeAsync
+, module Aws.Lambda.Commands.ListEventSources
+, module Aws.Lambda.Commands.ListFunctions
+, module Aws.Lambda.Commands.RemoveEventSource
+, module Aws.Lambda.Commands.UpdateFunctionConfiguration
+, module Aws.Lambda.Commands.UploadFunction
+) where
+
+import Aws.Lambda.Core
+import Aws.Lambda.Types
+
+import Aws.Lambda.Commands.AddEventSource
+import Aws.Lambda.Commands.DeleteFunction
+import Aws.Lambda.Commands.GetEventSource
+import Aws.Lambda.Commands.GetFunction
+import Aws.Lambda.Commands.GetFunctionConfiguration
+import Aws.Lambda.Commands.InvokeAsync
+import Aws.Lambda.Commands.ListEventSources
+import Aws.Lambda.Commands.ListFunctions
+import Aws.Lambda.Commands.RemoveEventSource
+import Aws.Lambda.Commands.UpdateFunctionConfiguration
+import Aws.Lambda.Commands.UploadFunction
+
diff --git a/src/Aws/Lambda/Commands/AddEventSource.hs b/src/Aws/Lambda/Commands/AddEventSource.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Commands/AddEventSource.hs
@@ -0,0 +1,136 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Commands.AddEventSource
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Commands.AddEventSource
+( -- * Request
+  AddEventSource(..)
+, addEventSource
+
+  -- ** Lenses
+, aesBatchSize
+, aesEventSource
+, aesFunctionName
+, aesParameters
+, aesRole
+
+  -- * Response
+, AddEventSourceResponse(..)
+
+  -- ** Lenses
+, aesrConfiguration
+) where
+
+import Aws.Lambda.Core
+import Aws.Lambda.Internal.Constraints
+import Aws.Lambda.Types
+
+import Control.Lens hiding ((.=))
+import Data.Aeson
+import Data.Monoid
+import qualified Data.Text as T
+import Network.HTTP.Types
+import Prelude.Unicode
+
+-- | Identifies a stream as an event source for an AWS Lambda function. It can
+-- be either an Amazon Kinesis stream or a Amazon DynamoDB stream. AWS Lambda
+-- invokes the specified function when records are posted to the stream.  This
+-- is the pull model, where AWS Lambda invokes the function.
+--
+-- This association between an Amazon Kinesis stream and an AWS Lambda function
+-- is called the event source mapping. You provide the configuration
+-- information (for example, which stream to read from and which AWS Lambda
+-- function to invoke) for the event source mapping in the request body.
+--
+-- Each event source, such as a Kinesis stream, can only be associated with one
+-- AWS Lambda function. If you call 'AddEventSource' for an event source that is
+-- already mapped to another AWS Lambda function, the existing mapping is
+-- updated to call the new function instead of the old one.
+--
+-- This operation requires permission for the @iam:PassRole@ action for the IAM
+-- role. It also requires permission for the @lambda:AddEventSource@ action.
+--
+data AddEventSource
+  = AddEventSource
+  { _aesBatchSize ∷ !(Maybe Integer)
+  -- ^ The largest number of records that AWS Lambda will give to your function
+  -- in a single event. The default is 100 records.
+
+  , _aesEventSource ∷ !Arn
+  -- ^ The Amazon Resource Name (ARN) of the Amazon Kinesis stream that is the
+  -- event source. Any record added to this stream causes AWS Lambda to invoke
+  -- your Lambda function. AWS Lambda POSTs the Amazon Kinesis event,
+  -- containing records, to your Lambda function as JSON.
+
+  , _aesFunctionName ∷ !T.Text
+  -- ^ The Lambda function to invoke when AWS Lambda detects an event on the
+  -- stream.
+
+  , _aesParameters ∷ !(Maybe EventSourceParameters)
+
+  , _aesRole ∷ !T.Text
+  -- ^ The ARN of the IAM role (invocation role) that AWS Lambda can assume to
+  -- read from the stream and invoke the function.
+
+  } deriving (Eq, Show)
+
+-- | A minimal 'AddEventSource' request.
+--
+addEventSource
+  ∷ Arn -- ^ '_aesEventSource'
+  → T.Text -- ^ '_aesFunctionName'
+  → Arn -- ^ '_aesRole'
+  → AddEventSource
+addEventSource es fn rl = AddEventSource
+  { _aesBatchSize = Nothing
+  , _aesEventSource = es
+  , _aesFunctionName = fn
+  , _aesParameters = Nothing
+  , _aesRole = rl
+  }
+
+instance ToJSON AddEventSource where
+  toJSON AddEventSource{..} = Object $
+    mempty
+      & (at "BatchSize" .~ _aesBatchSize ^? _Just ∘ to toJSON)
+      & (at "EventSource" ?~ toJSON _aesEventSource)
+      & (at "FunctionName" ?~ toJSON _aesFunctionName)
+      & (at "Parameters" .~ _aesParameters ^? _Just ∘ to toJSON)
+      & (at "Role" ?~ toJSON _aesRole)
+
+instance LambdaPayload AddEventSource where
+  packagePayload = Pack ∘ toJSON
+
+makeLenses ''AddEventSource
+
+newtype AddEventSourceResponse
+  = AddEventSourceResponse
+  { _aesrConfiguration ∷ EventSourceConfiguration
+  } deriving (Eq, Show, FromJSON)
+
+makeLenses ''AddEventSourceResponse
+
+instance LambdaTransaction AddEventSource AddEventSource AddEventSourceResponse where
+  buildQuery aes =
+    lambdaQuery' POST ["event-source-mappings"] aes
diff --git a/src/Aws/Lambda/Commands/DeleteFunction.hs b/src/Aws/Lambda/Commands/DeleteFunction.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Commands/DeleteFunction.hs
@@ -0,0 +1,69 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Commands.DeleteFunction
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Commands.DeleteFunction
+( -- * Request
+  DeleteFunction(..)
+, deleteFunction
+  -- ** Lenses
+, dfFunctionName
+
+  -- * Response
+, DeleteFunctionResponse(..)
+) where
+
+import Aws.Lambda.Core
+
+import Control.Lens
+import Data.Aeson
+import qualified Data.Text as T
+import Network.HTTP.Types
+
+-- | Deletes the specified Lambda function code and configuration.  This
+-- operation requires permission for the @lambda:DeleteFunction@ action.
+--
+data DeleteFunction
+  = DeleteFunction
+  { _dfFunctionName ∷ !T.Text
+  } deriving (Eq, Show)
+
+-- | A minimal 'DeleteFunction' request.
+--
+deleteFunction
+  ∷ T.Text
+  → DeleteFunction
+deleteFunction = DeleteFunction
+
+makeLenses ''DeleteFunction
+
+data DeleteFunctionResponse
+  = DeleteFunctionResponse
+  deriving (Eq, Show)
+
+instance FromJSON DeleteFunctionResponse where
+  parseJSON _ = return DeleteFunctionResponse
+
+instance LambdaTransaction DeleteFunction () DeleteFunctionResponse where
+  buildQuery df =
+    lambdaQuery DELETE ["functions", df ^. dfFunctionName]
+
diff --git a/src/Aws/Lambda/Commands/GetEventSource.hs b/src/Aws/Lambda/Commands/GetEventSource.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Commands/GetEventSource.hs
@@ -0,0 +1,74 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Commands.GetEventSource
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Commands.GetEventSource
+( -- * Request
+  GetEventSource(..)
+, getEventSource
+  -- ** Lenses
+, gesUuid
+
+  -- * Response
+, GetEventSourceResponse(..)
+  -- ** Lenses
+, gesrConfiguration
+) where
+
+import Aws.Lambda.Core
+import Aws.Lambda.Types
+
+import Control.Lens
+import Data.Aeson
+import Network.HTTP.Types
+import Prelude.Unicode
+
+-- | Returns configuration information for the specified event source mapping.
+-- This operation requires permission for the @lambda:GetEventSource@ action.
+--
+data GetEventSource
+  = GetEventSource
+  { _gesUuid ∷ !LambdaUuid
+  -- ^ The AWS Lambda assigned ID of the event source mapping.
+  } deriving (Eq, Show)
+
+makeLenses ''GetEventSource
+
+-- | A minimal 'GetEventSource' request.
+--
+getEventSource
+  ∷ LambdaUuid -- ^ '_gesUuid'
+  → GetEventSource
+getEventSource = GetEventSource
+
+newtype GetEventSourceResponse
+  = GetEventSourceResponse
+  { _gesrConfiguration ∷ EventSourceConfiguration
+  } deriving (Eq, Show, FromJSON)
+
+makeLenses ''GetEventSourceResponse
+
+instance LambdaTransaction GetEventSource () GetEventSourceResponse where
+  buildQuery ges =
+    lambdaQuery GET ["event-source-mappings", ges ^. gesUuid ∘ luText]
+
diff --git a/src/Aws/Lambda/Commands/GetFunction.hs b/src/Aws/Lambda/Commands/GetFunction.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Commands/GetFunction.hs
@@ -0,0 +1,88 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Commands.GetFunction
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Commands.GetFunction
+( -- * Request
+  GetFunction(..)
+, getFunction
+  -- ** Lenses
+, gfFunctionName
+
+  -- * Reponse
+, GetFunctionResponse(..)
+  -- ** Lenses
+, gfrCode
+, gfrConfiguration
+) where
+
+import Aws.Lambda.Core
+import Aws.Lambda.Types
+
+import Control.Applicative
+import Control.Applicative.Unicode
+import Control.Lens
+import Data.Aeson
+import Network.HTTP.Types
+import qualified Data.Text as T
+
+-- | Returns the configuration information of the Lambda function and a
+-- presigned URL link to the @.zip@ file you uploaded with @UploadFunction@ so
+-- you can download the @.zip@ file. Note that the URL is valid for up to 10
+-- minutes.  The configuration information is the same information you provided
+-- as parameters when uploading the function.
+--
+-- This operation requires permission for the @lambda:GetFunction@ action.
+--
+data GetFunction
+  = GetFunction
+  { _gfFunctionName ∷ !T.Text
+  } deriving (Eq, Show)
+
+makeLenses ''GetFunction
+
+-- | A minimal 'GetFunction' request.
+--
+getFunction
+  ∷ T.Text -- ^ '_gfFunctionName'
+  → GetFunction
+getFunction = GetFunction
+
+data GetFunctionResponse
+  = GetFunctionResponse
+  { _gfrCode ∷ !FunctionCodeLocation
+  , _gfrConfiguration ∷ !FunctionConfiguration
+  } deriving (Eq, Show)
+
+makeLenses ''GetFunctionResponse
+
+instance FromJSON GetFunctionResponse where
+  parseJSON =
+    withObject "GetFunctionResponse" $ \o →
+      pure GetFunctionResponse
+        ⊛ o .: "Code"
+        ⊛ o .: "Configuration"
+
+instance LambdaTransaction GetFunction () GetFunctionResponse where
+  buildQuery gf =
+    lambdaQuery GET ["functions", gf ^. gfFunctionName]
+
diff --git a/src/Aws/Lambda/Commands/GetFunctionConfiguration.hs b/src/Aws/Lambda/Commands/GetFunctionConfiguration.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Commands/GetFunctionConfiguration.hs
@@ -0,0 +1,67 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Commands.GetFunctionConfiguration
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Commands.GetFunctionConfiguration
+( -- * Request
+  GetFunctionConfiguration(..)
+, getFunctionConfiguration
+  -- ** Lenses
+, gfcFunctionName
+) where
+
+import Aws.Lambda.Core
+import Aws.Lambda.Types
+
+import Control.Lens
+import Data.Aeson
+import qualified Data.Text as T
+import Network.HTTP.Types
+
+-- | Returns the configuration information of the Lambda function. This the
+-- same information you provided as parameters when uploading the function by
+-- using @UploadFunction@.
+--
+-- This operation requires permission for the @lambda:GetFunctionConfiguration@
+-- operation.
+--
+data GetFunctionConfiguration
+  = GetFunctionConfiguration
+  { _gfcFunctionName ∷ !T.Text
+  } deriving (Eq, Show)
+
+makeLenses ''GetFunctionConfiguration
+
+getFunctionConfiguration
+  ∷ T.Text -- ^ '_gfcFunctionName'
+  → GetFunctionConfiguration
+getFunctionConfiguration = GetFunctionConfiguration
+
+newtype GetFunctionConfigurationResponse
+  = GetFunctionConfigurationResponse
+  { _gfcrFunctionConfiguration ∷ FunctionConfiguration
+  } deriving (Eq, Show, FromJSON)
+
+instance LambdaTransaction GetFunctionConfiguration () GetFunctionConfigurationResponse where
+  buildQuery gfc =
+    lambdaQuery GET ["functions", gfc ^. gfcFunctionName, "configuration"]
diff --git a/src/Aws/Lambda/Commands/InvokeAsync.hs b/src/Aws/Lambda/Commands/InvokeAsync.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Commands/InvokeAsync.hs
@@ -0,0 +1,79 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Commands.InvokeAsync
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Commands.InvokeAsync
+( -- * Request
+  InvokeAsync(..)
+, invokeAsync
+  -- ** Lenses
+, iaFunctionName
+, iaArguments
+
+  -- * Response
+, InvokeAsyncResponse(..)
+) where
+
+import Aws.Lambda.Core
+
+import Control.Applicative
+import Control.Lens
+import Data.Aeson
+import qualified Data.Text as T
+import Network.HTTP.Types
+
+-- | Submits an invocation request to AWS Lambda. Upon receiving the request,
+-- Lambda executes the specified function asynchronously. To see the logs
+-- generated by the Lambda function execution, see the CloudWatch logs console.
+--
+-- This operation requires permission for the @lambda:InvokeAsync@ action.
+--
+data InvokeAsync
+  = InvokeAsync
+  { _iaFunctionName ∷ !T.Text
+  , _iaArguments ∷ !Value
+  } deriving (Eq, Show)
+
+makeLenses ''InvokeAsync
+
+-- | A minimal 'InvokeAsync' request.
+--
+invokeAsync
+  ∷ T.Text -- ^ '_iaFunctionName'
+  → InvokeAsync
+invokeAsync fn = InvokeAsync fn $ object []
+
+data InvokeAsyncResponse
+  = InvokeAsyncResponse
+  deriving (Eq, Show)
+
+makeLenses ''InvokeAsyncResponse
+
+instance FromJSON InvokeAsyncResponse where
+  parseJSON _ = pure InvokeAsyncResponse
+
+instance LambdaTransaction InvokeAsync Value InvokeAsyncResponse where
+  buildQuery ia =
+    lambdaQuery'
+      POST
+      ["functions", ia ^. iaFunctionName, "invoke-async"]
+      (ia ^. iaArguments)
diff --git a/src/Aws/Lambda/Commands/ListEventSources.hs b/src/Aws/Lambda/Commands/ListEventSources.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Commands/ListEventSources.hs
@@ -0,0 +1,125 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Commands.ListEventSources
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Commands.ListEventSources
+( -- * Request
+  ListEventSources(..)
+, listEventSources
+  -- ** Lenses
+, lesEventSourceArn
+, lesFunctionName
+, lesMarker
+, lesMaxItems
+
+  -- * Response
+, ListEventSourcesResponse(..)
+  -- ** Lenses
+, lesrEventSources
+, lesrNextMarker
+) where
+
+import Aws.Lambda.Core
+import Aws.Lambda.Types
+
+import Control.Applicative
+import Control.Applicative.Unicode
+import Control.Lens
+import Data.Aeson
+import qualified Data.Text as T
+import Network.HTTP.Types
+import Prelude.Unicode
+
+-- | Returns a list of event source mappings you created using the
+-- @AddEventSource@ action, where you identify a stream as event source. This
+-- list does not include Amazon S3 event sources.
+--
+-- For each mapping, the API returns configuration information. You can
+-- optionally specify filters to retrieve specific event source mappings.
+--
+-- This operation requires permission for the @lambda:ListEventSources@ action.
+--
+data ListEventSources
+  = ListEventSources
+  { _lesEventSourceArn ∷ !Arn
+    -- ^ The Amazon Resource Name (ARN) of the event source.
+
+  , _lesFunctionName ∷ !T.Text
+    -- ^ The name of the AWS Lambda function.
+
+  , _lesMarker ∷ !(Maybe PaginationToken)
+    -- ^ Optional, returned from previous 'ListEventSources' request; if
+    -- present, specifies to continue the list from where the returning call
+    -- left off.
+
+  , _lesMaxItems ∷ !(Maybe Int)
+    -- ^ Optional, maximum number of event sources to return. Length
+    -- constraints: @1 ≤ n ≤ 1000@.
+  } deriving (Eq, Show)
+
+makeLenses ''ListEventSources
+
+-- | Create a minimal 'ListEventSources' request.
+--
+listEventSources
+  ∷ Arn -- ^ The event source ARN
+  → T.Text -- ^ The function name
+  → ListEventSources
+listEventSources arn func = ListEventSources
+  { _lesEventSourceArn = arn
+  , _lesFunctionName = func
+  , _lesMarker = Nothing
+  , _lesMaxItems = Nothing
+  }
+
+data ListEventSourcesResponse
+  = ListEventSourcesResponse
+  { _lesrEventSources ∷ ![EventSourceConfiguration]
+    -- ^ A list of 'EventSourceConfiguration' objects.
+
+  , _lesrNextMarker ∷ !(Maybe PaginationToken)
+    -- ^ Present if there are more event source mappings.
+  } deriving (Eq, Show)
+
+makeLenses ''ListEventSourcesResponse
+
+instance FromJSON ListEventSourcesResponse where
+  parseJSON =
+    withObject "ListEventSourcesResponse" $ \o →
+      pure ListEventSourcesResponse
+        ⊛ o .:? "EventSources" .!= []
+        ⊛ o .:? "NextMarker"
+
+instance LambdaTransaction ListEventSources () ListEventSourcesResponse where
+  buildQuery les =
+    lambdaQuery GET ["event-source-mappings"]
+      & lqParams
+        %~ (at "EventSourceArn" ?~ les ^. lesEventSourceArn ∘ to arnToText)
+         ∘ (at "FunctionName" ?~ les ^. lesFunctionName)
+         ∘ (at "Marker" .~ les ^? lesMarker ∘ _Just ∘ ptText)
+         ∘ (at "MaxItems" .~ les ^? lesMaxItems ∘ _Just ∘ to (T.pack ∘ show))
+
+instance PagedLambdaTransaction ListEventSources () ListEventSourcesResponse PaginationToken [EventSourceConfiguration] where
+  requestCursor = lesMarker
+  responseCursor = lesrNextMarker
+  responseAccum = lesrEventSources
diff --git a/src/Aws/Lambda/Commands/ListFunctions.hs b/src/Aws/Lambda/Commands/ListFunctions.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Commands/ListFunctions.hs
@@ -0,0 +1,109 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Commands.ListFunctions
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Commands.ListFunctions
+( -- * Request
+  ListFunctions(..)
+, listFunctions
+  -- ** Lenses
+, lfMarker
+, lfMaxItems
+
+  -- * Response
+, ListFunctionsResponse
+  -- ** Lenses
+, lfrNextMarker
+, lfrFunctions
+) where
+
+import Aws.Lambda.Core
+import Aws.Lambda.Types
+
+import Control.Applicative
+import Control.Applicative.Unicode
+import Control.Lens
+import Data.Aeson
+import qualified Data.Text as T
+import Network.HTTP.Types
+import Prelude.Unicode
+
+-- | Returns a list of your Lambda functions. For each function, the response
+-- includes the function configuration information. You must use @GetFunction@ to
+-- retrieve the code for your function.
+--
+-- This operation requires permission for the @lambda:ListFunctions@ action.
+--
+
+data ListFunctions
+  = ListFunctions
+  { _lfMarker ∷ !(Maybe PaginationToken)
+  -- ^  An opaque pagination token returned from a previous 'ListFunctions'
+  -- operation. If present, indicates where to continue the listing.
+
+  , _lfMaxItems ∷ !(Maybe Int)
+  -- ^ Specifies the maximum number of AWS Lambda functions to return in
+  -- response. This parameter value must be greater than @0@ and less than
+  -- @10000@.
+  } deriving (Eq, Show)
+
+makeLenses ''ListFunctions
+
+-- | A minimal 'ListFunctions' request.
+--
+listFunctions ∷ ListFunctions
+listFunctions = ListFunctions
+  { _lfMarker = Nothing
+  , _lfMaxItems = Nothing
+  }
+
+data ListFunctionsResponse
+  = ListFunctionsResponse
+  { _lfrFunctions ∷ ![FunctionConfiguration]
+  -- ^ A list of Lambda functions.
+
+  , _lfrNextMarker ∷ !(Maybe PaginationToken)
+  -- ^ A token whose presence indicates that more functions are available.
+  } deriving (Eq, Show)
+
+makeLenses ''ListFunctionsResponse
+
+instance FromJSON ListFunctionsResponse where
+  parseJSON =
+    withObject "ListFunctionsResponse" $ \o →
+      pure ListFunctionsResponse
+        ⊛ o .:? "Functions" .!= []
+        ⊛ o .:? "NextMarker"
+
+instance LambdaTransaction ListFunctions () ListFunctionsResponse where
+  buildQuery lf =
+    lambdaQuery GET ["functions"]
+      & lqParams
+        %~ (at "Marker" .~ lf ^? lfMarker ∘ _Just ∘ ptText)
+         ∘ (at "MaxItems" .~ lf ^? lfMaxItems ∘ _Just ∘ to (T.pack ∘ show))
+
+instance PagedLambdaTransaction ListFunctions () ListFunctionsResponse PaginationToken [FunctionConfiguration] where
+  requestCursor = lfMarker
+  responseCursor = lfrNextMarker
+  responseAccum = lfrFunctions
+
diff --git a/src/Aws/Lambda/Commands/RemoveEventSource.hs b/src/Aws/Lambda/Commands/RemoveEventSource.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Commands/RemoveEventSource.hs
@@ -0,0 +1,72 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Commands.RemoveEventSource
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Commands.RemoveEventSource
+( -- * Request
+  RemoveEventSource(..)
+, removeEventSource
+  -- ** Lenses
+, resUuid
+
+  -- * Response
+, RemoveEventSourceResponse(..)
+) where
+
+import Aws.Lambda.Core
+import Aws.Lambda.Types
+
+import Data.Aeson
+import Control.Lens
+import Network.HTTP.Types
+import Prelude.Unicode
+
+-- | Removes an event source mapping. This means AWS Lambda will no longer
+-- invoke the function for events in the associated source.
+--
+-- This operation requires permission for the @lambda:RemoveEventSource@ action.
+--
+data RemoveEventSource
+  = RemoveEventSource
+  { _resUuid ∷ !LambdaUuid
+  -- ^ The event source mapping ID.
+  }
+
+-- | A minimal 'RemoveEventSource' request.
+--
+removeEventSource
+  ∷ LambdaUuid -- ^ '_resUuid'
+  → RemoveEventSource
+removeEventSource = RemoveEventSource
+
+makeLenses ''RemoveEventSource
+
+data RemoveEventSourceResponse
+  = RemoveEventSourceResponse
+  deriving (Eq, Show)
+
+instance FromJSON RemoveEventSourceResponse where
+  parseJSON _ = return RemoveEventSourceResponse
+
+instance LambdaTransaction RemoveEventSource () RemoveEventSourceResponse where
+  buildQuery res =
+    lambdaQuery DELETE ["event-source-mappings", res ^. resUuid ∘ luText]
diff --git a/src/Aws/Lambda/Commands/UpdateFunctionConfiguration.hs b/src/Aws/Lambda/Commands/UpdateFunctionConfiguration.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Commands/UpdateFunctionConfiguration.hs
@@ -0,0 +1,116 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Commands.UpdateFunctionConfiguration
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Commands.UpdateFunctionConfiguration
+( -- * Request
+  UpdateFunctionConfiguration
+, updateFunctionConfiguration
+  -- ** Lenses
+, ufcConfiguration
+
+  -- * Response
+, UpdateFunctionConfigurationResponse(..)
+  -- ** Lenses
+, ufcrFunctionConfiguration
+
+  -- * Exceptions
+, UpdateFunctionConfigurationException(..)
+, _MissingFunctionName
+) where
+
+import Aws.Lambda.Core
+import Aws.Lambda.Types
+
+import Control.Exception
+import Control.Lens
+import Control.Monad.Catch
+import Data.Aeson
+import qualified Data.Text as T
+import Data.Typeable
+import Network.HTTP.Types
+import Prelude.Unicode
+
+-- | Updates the configuration parameters for the specified Lambda function by
+-- using the values provided in the request. You provide only the parameters
+-- you want to change. This operation must only be used on an existing Lambda
+-- function and cannot be used to update the function's code.
+--
+-- This operation requires permission for the
+-- @lambda:UpdateFunctionConfiguration@ action.
+--
+-- The 'UpdateFunctionConfiguration' type is abstract.
+--
+data UpdateFunctionConfiguration
+  = UpdateFunctionConfiguration
+  { _ufcConfiguration ∷ !FunctionConfiguration
+  , _ufcFunctionName ∷ !T.Text
+  } deriving (Eq, Show)
+
+ufcConfiguration ∷ Getter UpdateFunctionConfiguration FunctionConfiguration
+ufcConfiguration = to _ufcConfiguration
+
+ufcFunctionName ∷ Getter UpdateFunctionConfiguration T.Text
+ufcFunctionName = to _ufcFunctionName
+
+data UpdateFunctionConfigurationException
+  = MissingFunctionName !FunctionConfiguration
+  deriving (Eq, Show, Typeable)
+
+makePrisms ''UpdateFunctionConfigurationException
+
+instance Exception UpdateFunctionConfigurationException
+
+-- | A minimal, validated 'UpdateFunctionConfiguration' request. Not providing
+-- '_fcFunctionName' will result in an exception.
+--
+updateFunctionConfiguration
+  ∷ MonadThrow m
+  ⇒ FunctionConfiguration
+  → m UpdateFunctionConfiguration
+updateFunctionConfiguration fc =
+  case fc ^. fcFunctionName of
+    Just fn → return UpdateFunctionConfiguration
+      { _ufcConfiguration = fc
+      , _ufcFunctionName = fn
+      }
+    Nothing → throwM $ MissingFunctionName fc
+
+newtype UpdateFunctionConfigurationResponse
+  = UpdateFunctionConfigurationResponse
+  { _ufcrFunctionConfiguration ∷ FunctionConfiguration
+  } deriving (Eq, Show, FromJSON)
+
+makeLenses ''UpdateFunctionConfigurationResponse
+
+instance LambdaTransaction UpdateFunctionConfiguration () UpdateFunctionConfigurationResponse where
+  buildQuery ufc =
+    let fc = ufc ^. ufcConfiguration
+    in lambdaQuery PUT ["functions", ufc ^. ufcFunctionName, "configuration"]
+      & lqParams
+        %~ (at "Description" .~ fc ^. fcDescription)
+         ∘ (at "Handler" .~ fc ^. fcHandler)
+         ∘ (at "MemorySize" .~ fc ^? fcMemorySize ∘ _Just ∘ to (T.pack ∘ show))
+         ∘ (at "Role" .~ fc ^? fcRole ∘ _Just ∘ to arnToText)
+         ∘ (at "Timeout" .~ fc ^? fcTimeout ∘ _Just ∘ to (T.pack ∘ show))
diff --git a/src/Aws/Lambda/Commands/UploadFunction.hs b/src/Aws/Lambda/Commands/UploadFunction.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Commands/UploadFunction.hs
@@ -0,0 +1,144 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Commands.UploadFunction
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE UnicodeSyntax #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Aws.Lambda.Commands.UploadFunction
+( -- * Request
+  UploadFunction(..)
+  -- ** Lenses
+, ufDescription
+, ufFunctionName
+, ufHandler
+, ufMemorySize
+, ufMode
+, ufRole
+, ufRuntime
+, ufTimeout
+, ufRawCode
+, ufLastModified
+) where
+
+import Aws.Lambda.Core
+import Aws.Lambda.Types
+
+import qualified Codec.Archive.Zip as Z
+import Control.Lens hiding ((<.>))
+import Data.Aeson
+import qualified Data.ByteString as B
+import qualified Data.ByteString.Lazy as LB
+import qualified Data.Text as T
+import Data.Time
+import Data.Time.Clock.POSIX
+import Network.HTTP.Types
+import Prelude.Unicode
+import System.FilePath
+
+-- | Creates a new Lambda function or updates an existing function. The
+-- function metadata is created from the request parameters, and the code for
+-- the function is provided by a @.zip@ file in the request body. If the
+-- function name already exists, the existing Lambda function is updated with
+-- the new code and metadata.
+--
+-- This operation requires permission for the @lambda:UploadFunction@ action.
+--
+-- Note that these bindings take care of packaging up the function source code
+-- as a @.zip@ file automatically.
+--
+data UploadFunction
+  = UploadFunction
+  { _ufDescription ∷ !T.Text
+  -- ^ A short, user-defined function description. Lambda does not use this
+  -- value. Assign a meaningful description as you see fit.
+
+  , _ufFunctionName ∷ !T.Text
+  -- ^ The name you want to assign to the function you are uploading.
+
+  , _ufHandler ∷ !T.Text
+  -- ^ The function that Lambda calls to begin execution. For Node.js, it is
+  -- the @module-name.export@ value in your function
+
+  , _ufMemorySize ∷ !Int
+  -- ^ The amount of memory, in MB, your Lambda function is given. Lambda uses
+  -- this memory size to infer the amount of CPU allocated to your function.
+  -- Your function use-case determines your CPU and memory requirements. For
+  -- example, database operation might need less memory compared to image
+  -- processing function. The default value is 128 MB. The value must be a
+  -- multiple of 64 MB.
+
+  , _ufMode ∷ !FunctionMode
+  -- ^ How the Lambda function will be invoked.
+
+  , _ufRole ∷ !Arn
+  -- ^ The Amazon Resource Name (ARN) of the IAM role that Lambda assumes when
+  -- it executes your function to access any other Amazon Web Services (AWS)
+  -- resources.
+
+  , _ufRuntime ∷ !FunctionRuntime
+  -- ^ The runtime environment for the Lambda function you are uploading.
+
+  , _ufTimeout ∷ !Int
+  -- ^ The function execution time at which Lambda should terminate the
+  -- function. Because the execution time has cost implications, we recommend
+  -- you set this value based on your expected execution time. The default is 3
+  -- seconds.
+
+  , _ufRawCode ∷ !B.ByteString
+  -- ^ The raw code of the function (which will be packaged into a ZIP archive
+  -- automatically).
+
+  , _ufLastModified ∷ !UTCTime
+  -- ^ The last-modified date to be assigned to the file in the ZIP archive.
+  } deriving (Eq, Show)
+
+makeLenses ''UploadFunction
+
+newtype UploadFunctionResponse
+  = UploadFunctionResponse
+  { _ufrConfiguration ∷ FunctionConfiguration
+  } deriving (Eq, Show, FromJSON)
+
+instance LambdaTransaction UploadFunction B.ByteString UploadFunctionResponse where
+  buildQuery uf =
+    lambdaQuery' PUT ["functions", uf ^. ufFunctionName] archivedSource
+      & lqParams
+        %~ (at "Description" ?~ uf ^. ufDescription)
+         ∘ (at "Handler" ?~ uf ^. ufHandler)
+         ∘ (at "MemorySize" ?~ uf ^. ufMemorySize ∘ to (T.pack ∘ show))
+         ∘ (at "Mode" ?~ uf ^. ufMode ∘ re _TextFunctionMode)
+         ∘ (at "Role" ?~ uf ^. ufRole ∘ to arnToText)
+         ∘ (at "Runtime" ?~ uf ^. ufRuntime ∘ re _TextFunctionRuntime)
+         ∘ (at "Timeout" ?~ uf ^. ufTimeout ∘ to (T.pack ∘ show))
+    where
+      extension =
+        case uf ^. ufRuntime of
+          FunctionRuntimeNodeJs → "js"
+
+      archivedSource =
+        LB.toStrict ∘ Z.fromArchive ∘ flip Z.addEntryToArchive Z.emptyArchive $
+          Z.toEntry
+            (uf ^. ufFunctionName ∘ to T.unpack <.> extension)
+            (uf ^. ufLastModified ∘ to (round ∘ utcTimeToPOSIXSeconds))
+            (uf ^. ufRawCode ∘ to LB.fromStrict)
+
diff --git a/src/Aws/Lambda/Core.hs b/src/Aws/Lambda/Core.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Core.hs
@@ -0,0 +1,288 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Core
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Core
+( -- * Client configuration
+  LambdaConfiguration(..)
+  -- ** Lenses
+, lcRegion
+, lcAccessKeyId
+, lcSecretAccessKey
+
+  -- * Client query
+, LambdaQuery(..)
+, lambdaQuery
+, lambdaQuery'
+  -- ** Lenses
+, lqMethod
+, lqPath
+, lqParams
+, lqBody
+
+  -- * Transaction machinery
+, LambdaTransaction(..)
+, LambdaPayload(..)
+, PagedLambdaTransaction(..)
+
+  -- * Exceptions
+, InvalidHttpMethodException
+, _InvalidHttpMethodException
+, InvalidRegionException
+, _InvalidRegionException
+
+  -- ** Exception Patterns
+, pattern InvalidParameterValueException
+, pattern ResourceNotFoundException
+, pattern ServiceException
+) where
+
+import Aws.General
+import Aws.Lambda.Internal.Constraints
+
+import Control.Applicative
+import Control.Lens
+import Control.Monad.Catch
+import Control.Monad.Trans
+import Control.Monad.Unicode
+
+import qualified Data.Aeson as AE
+import qualified Data.ByteString as B
+import qualified Data.ByteString.Lazy as LB
+import qualified Data.Map as M
+import Data.Monoid
+import Data.Monoid.Unicode
+import qualified Data.Text as T
+import Data.Typeable
+import Network.HTTP.Types
+import Network.HTTP.Client
+import qualified Network.Wreq as W
+import qualified Network.Wreq.Types as WT
+import Prelude.Unicode
+
+data LambdaConfiguration
+  = LambdaConfiguration
+  { _lcRegion ∷ !Region
+  , _lcAccessKeyId ∷ !B.ByteString
+  , _lcSecretAccessKey ∷ !B.ByteString
+  } deriving (Eq, Show)
+
+makeLenses ''LambdaConfiguration
+
+lambdaOptions
+  ∷ LambdaConfiguration
+  → W.Options
+  → W.Options
+lambdaOptions lc =
+  foldr (∘) id $
+    [ W.auth ?~ W.awsAuth W.AWSv4 (lc ^. lcAccessKeyId) (lc ^. lcSecretAccessKey)
+    , W.header "Accept" .~ ["application/json"]
+    ]
+
+class LambdaPayload body where
+  packagePayload
+    ∷ body
+    → Σ (WT.Postable ⊗ WT.Putable)
+
+instance LambdaPayload () where
+  packagePayload () = Pack B.empty
+instance LambdaPayload B.ByteString where
+  packagePayload b = Pack b
+instance LambdaPayload AE.Value where
+  packagePayload x = Pack x
+
+data LambdaQuery body
+  = LambdaQuery
+  { _lqBody ∷ !body
+  , _lqParams ∷ !(M.Map T.Text T.Text)
+  , _lqPath ∷ ![T.Text]
+  , _lqMethod ∷ !StdMethod
+  } deriving (Eq, Show)
+
+makeLenses ''LambdaQuery
+
+-- | A convenience constructor for a basic query.
+--
+lambdaQuery
+  ∷ Monoid body
+  ⇒ StdMethod
+  → [T.Text]
+  → LambdaQuery body
+lambdaQuery meth p = LambdaQuery
+  { _lqMethod = meth
+  , _lqPath = p
+  , _lqBody = mempty
+  , _lqParams = M.empty
+  }
+
+-- | A variant of 'lambdaQuery' that requires a body.
+--
+lambdaQuery'
+  ∷ StdMethod
+  → [T.Text]
+  → body
+  → LambdaQuery body
+lambdaQuery' meth p b = LambdaQuery
+  { _lqMethod = meth
+  , _lqPath = p
+  , _lqBody = b
+  , _lqParams = M.empty
+  }
+
+newtype InvalidRegionException
+  = InvalidRegionException
+  { _ireRegion ∷ Region
+  } deriving (Eq, Show, Typeable)
+instance Exception InvalidRegionException
+
+makePrisms ''InvalidRegionException
+
+lambdaEndpointUrl
+  ∷ MonadThrow m
+  ⇒ Region -- ^ The AWS region to target
+  → [T.Text] -- ^ The path of the AWS Lambda endpoint
+  → m String
+lambdaEndpointUrl r e = do
+  subdomain ← case r of
+    UsWest2 → return "us-west-2"
+    UsEast1 → return "us-east-1"
+    EuWest1 → return "eu-west-1"
+    _ → throwM $ InvalidRegionException r
+  return $
+    "https://lambda." ⊕ subdomain ⊕ ".amazonaws.com/2014-11-13/" ⊕ (T.unpack $ T.intercalate "/" e)
+
+liftThrow
+  ∷ ( MonadThrow m
+    , MonadIO m
+    )
+  ⇒ IO α
+  → m α
+liftThrow m = do
+  either throwM return =≪ do
+    liftIO $ catch
+      (fmap Right m)
+      (\(e ∷ SomeException) → return $ Left e)
+
+newtype InvalidHttpMethodException
+  = InvalidHttpMethodException
+  { _ihmeMethod ∷ StdMethod
+  } deriving (Eq, Show, Typeable)
+instance Exception InvalidHttpMethodException
+
+makePrisms ''InvalidHttpMethodException
+
+pattern InvalidParameterValueException msg
+  ← StatusCodeException (Status 400 msg) _ _
+pattern ResourceNotFoundException msg
+  ← StatusCodeException (Status 400 msg) _ _
+pattern ServiceException msg
+  ← StatusCodeException (Status 500 msg) _ _
+
+-- | A kludge to get around the fact that AWS Lambda sends back empty responses
+-- to some requests.
+--
+asJSON'
+  ∷ ( MonadThrow m
+    , MonadCatch m
+    , AE.FromJSON α
+    )
+  ⇒ Response LB.ByteString
+  → m (Response α)
+asJSON' resp =
+  catch (W.asJSON resp) $ \(_ ∷ WT.JSONError) → do
+    W.asJSON resp { responseBody = "{}" }
+
+-- | A class for associating a request type with a response type.
+--
+class (LambdaPayload body, AE.FromJSON resp) ⇒ LambdaTransaction req body resp | req → resp body, resp → req where
+
+  -- | Construct a 'LambdaQuery' object from the request data.
+  --
+  buildQuery
+    ∷ req
+    → LambdaQuery body
+
+  -- | Send the request to AWS Lambda.
+  --
+  runLambda
+    ∷ ( MonadThrow m
+      , MonadCatch m
+      , MonadIO m
+      )
+    ⇒ LambdaConfiguration
+    → req
+    → m resp
+  runLambda cfg req = do
+    let query = buildQuery req
+        opts = lambdaOptions cfg W.defaults
+          & W.params <>~ query ^. lqParams ∘ to M.toList
+        body = query ^. lqBody ∘ to packagePayload
+
+    url ← lambdaEndpointUrl (cfg ^. lcRegion) (query ^. lqPath)
+    spread body $ \payload → do
+      resp ← case query ^. lqMethod of
+        GET → liftThrow $ W.getWith opts url
+        POST → liftThrow $ W.postWith opts url payload
+        PUT → liftThrow $ W.putWith opts url payload
+        DELETE → liftThrow $ W.deleteWith opts url
+        meth → throwM $ InvalidHttpMethodException meth
+      resp ^! act asJSON' ∘ W.responseBody
+
+class (LambdaTransaction req body resp, Monoid acc) ⇒ PagedLambdaTransaction req body resp cur acc | req → resp cur acc where
+  -- | To set the cursor in subsequent requests.
+  --
+  requestCursor ∷ Setter' req (Maybe cur)
+
+  -- | To get the cursor in respones.
+  --
+  responseCursor ∷ Getter resp (Maybe cur)
+
+  -- | To get the accumulating portion of the response data.
+  --
+  responseAccum ∷ Getter resp acc
+
+  -- | Exhaustively iterates a request to AWS lambda and returns the
+  -- accumulated results.
+  --
+  pagedRunLambda
+    ∷ ( MonadThrow m
+      , MonadCatch m
+      , MonadIO m
+      , Functor m
+      )
+    ⇒ LambdaConfiguration
+    → req
+    → m acc
+  pagedRunLambda cfg req = do
+    resp ← runLambda cfg req
+    case resp ^. responseCursor of
+      Just cur →
+        mappend (resp ^. responseAccum)
+          <$> pagedRunLambda cfg (req & requestCursor ?~ cur)
+      Nothing →
+        return $
+          resp ^. responseAccum
diff --git a/src/Aws/Lambda/Internal/Constraints.hs b/src/Aws/Lambda/Internal/Constraints.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Internal/Constraints.hs
@@ -0,0 +1,58 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Internal.Constraints
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Internal.Constraints
+( Σ(..)
+, spread
+, type (⊗)
+) where
+
+import GHC.Exts (Constraint)
+
+-- | The pointwise product of two constraint families. This sadly requires
+-- @-XUndecidableInstances@.
+--
+class (γ α, δ α) ⇒ (γ ⊗ δ) α
+instance (γ α, δ α) ⇒ (γ ⊗ δ) α
+
+-- | The dependent sum of a constraint family.
+--
+data Σ (γ ∷ * → Constraint) where
+  Pack
+    ∷ γ α
+    ⇒ α
+    → Σ γ
+
+-- | The recursion principle for the constraint family sum.
+--
+spread
+  ∷ Σ γ
+  → (∀ α. γ α ⇒ α → β)
+  → β
+spread (Pack x) e = e x
+
diff --git a/src/Aws/Lambda/Internal/Utils.hs b/src/Aws/Lambda/Internal/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Internal/Utils.hs
@@ -0,0 +1,40 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Internal.Utils
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Internal.Utils
+( parserWithPrism
+) where
+
+import Control.Lens
+import qualified Data.Aeson.Types as AE
+import Data.Monoid.Unicode
+import qualified Data.Text as T
+
+parserWithPrism
+  ∷ Show α
+  ⇒ T.Text -- ^ A label for error messages
+  → Prism' α β -- ^ A prism whence to generate a parser
+  → α
+  → AE.Parser β
+parserWithPrism lbl p x =
+  case x ^? p of
+    Just v → return v
+    Nothing → fail $ "Invalid " ⊕ T.unpack lbl ⊕ ": " ⊕ show x
diff --git a/src/Aws/Lambda/Types.hs b/src/Aws/Lambda/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Aws/Lambda/Types.hs
@@ -0,0 +1,429 @@
+-- Copyright (c) 2013-2014 PivotCloud, Inc.
+--
+-- Aws.Lambda.Types
+--
+-- Please feel free to contact us at licensing@pivotmail.com with any
+-- contributions, additions, or other feedback; we would love to hear from
+-- you.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnicodeSyntax #-}
+
+module Aws.Lambda.Types
+( -- * Abstract types
+  PaginationToken
+, LambdaUuid
+, ConfigurationId
+
+  -- ** Lenses
+, ptText
+, cidText
+, luText
+
+  -- * Event Source Configuration
+, EventSourceConfiguration(..)
+, EventSourceParameters(..)
+, EventSourceStatus
+
+  -- ** Lenses
+, escBatchSize
+, escEventSource
+, escFunctionName
+, escIsActive
+, escLastModified
+, escParameters
+, escRole
+, escStatus
+, escUuid
+, espInitialPositionInStream
+
+  -- ** Prisms
+, _EventSourceStatusPending
+, _EventSourceStatusOk
+, _EventSourceStatusProblem
+, _TextEventSourceStatus
+
+  -- * Function Configuration
+, FunctionConfiguration(..)
+, emptyFunctionConfiguration
+, FunctionMode(..)
+, FunctionRuntime(..)
+, functionModeToText
+, functionRuntimeToText
+
+-- ** Lenses
+, fcCodeSize
+, fcConfigurationId
+, fcDescription
+, fcFunctionArn
+, fcFunctionName
+, fcHandler
+, fcLastModified
+, fcMemorySize
+, fcMode
+, fcRole
+, fcRuntime
+, fcTimeout
+
+  -- ** Prisms
+, _FunctionModeEvent
+, _FunctionRuntimeNodeJs
+, _TextFunctionMode
+, _TextFunctionRuntime
+
+-- * Misc
+, StreamPosition(..)
+, _StreamPositionTrimHorizon
+, _StreamPositionLatest
+, FunctionCodeLocation(..)
+, fclLocation
+, fclRepositoryType
+, Arn
+, arnToText
+, LambdaDateTime(..)
+, _LambdaDateTime
+, _TextLambdaDateTime
+) where
+
+import Aws.Lambda.Internal.Utils
+
+import Control.Applicative
+import Control.Applicative.Unicode
+import Control.Lens hiding ((.=))
+import Control.Monad.Unicode
+import Data.Aeson
+import Data.Aeson.Types
+import Data.Aeson.Lens
+import Data.Monoid
+import Data.Monoid.Unicode
+import qualified Data.Text as T
+import Data.Time
+import Prelude.Unicode
+import System.Locale
+
+type Arn = T.Text
+
+arnToText
+  ∷ Arn
+  → T.Text
+arnToText = id
+
+newtype PaginationToken
+  = PaginationToken
+  { _ptText ∷ T.Text
+  } deriving (Eq, Show)
+
+ptText ∷ Getter PaginationToken T.Text
+ptText = to _ptText
+
+instance FromJSON PaginationToken where
+  parseJSON =
+    withText "PaginationToken" $
+      pure ∘ PaginationToken
+
+instance ToJSON PaginationToken where
+  toJSON = String ∘ _ptText
+
+newtype LambdaUuid
+  = LambdaUuid
+  { _luText ∷ T.Text
+  } deriving (Eq, Show, ToJSON)
+
+luText ∷ Getter LambdaUuid T.Text
+luText = to _luText
+
+instance FromJSON LambdaUuid where
+  parseJSON =
+    withText "LambdaUuid" $
+      pure ∘ LambdaUuid
+
+data EventSourceStatus
+  = EventSourceStatusPending
+  | EventSourceStatusOk
+  | EventSourceStatusProblem T.Text
+  deriving (Eq, Show)
+
+makePrisms ''EventSourceStatus
+
+instance FromJSON EventSourceStatus where
+  parseJSON =
+    parserWithPrism "EventSourceStatus" $
+      _String ∘ _TextEventSourceStatus
+
+eventSourceStatusToText
+  ∷ EventSourceStatus
+  → T.Text
+eventSourceStatusToText = \case
+  EventSourceStatusPending → "PENDING"
+  EventSourceStatusOk → "OK"
+  EventSourceStatusProblem msg → "PROBLEM:" ⊕ msg
+
+_TextEventSourceStatus ∷ Prism' T.Text EventSourceStatus
+_TextEventSourceStatus =
+  prism eventSourceStatusToText $ \txt →
+    case (T.unpack $ T.toUpper txt) of
+      "PENDING" → Right EventSourceStatusPending
+      "OK" → Right EventSourceStatusOk
+      'P':'R':'O':'B':'L':'E':'M':':':msg → Right ∘ EventSourceStatusProblem $ T.pack msg
+      _ → Left txt
+
+data StreamPosition
+  = StreamPositionTrimHorizon
+  | StreamPositionLatest
+  deriving (Eq, Show)
+
+makePrisms ''StreamPosition
+
+instance FromJSON StreamPosition where
+  parseJSON =
+    parserWithPrism "StreamPosition" $
+      _String ∘ _TextStreamPosition
+
+instance ToJSON StreamPosition where
+  toJSON = review $ _String ∘ _TextStreamPosition
+
+streamPositionToText
+  ∷ StreamPosition
+  → T.Text
+streamPositionToText = \case
+  StreamPositionTrimHorizon → "TRIM_HORIZON"
+  StreamPositionLatest → "LATEST"
+
+_TextStreamPosition ∷ Prism' T.Text StreamPosition
+_TextStreamPosition =
+  prism streamPositionToText $ \case
+    "TRIM_HORIZON" → Right StreamPositionTrimHorizon
+    "LATEST" → Right StreamPositionLatest
+    txt → Left txt
+
+newtype LambdaDateTime
+  = LambdaDateTime
+  { _ldtUTCTime ∷ UTCTime
+  } deriving (Eq, Ord, Show, ParseTime, FormatTime)
+
+makePrisms ''LambdaDateTime
+
+lambdaDateTimeFormat ∷ String
+lambdaDateTimeFormat = "%FT%T%Q%Z"
+
+_TextLambdaDateTime ∷ Prism' T.Text LambdaDateTime
+_TextLambdaDateTime =
+  prism (T.pack ∘ formatTime defaultTimeLocale lambdaDateTimeFormat) $ \txt →
+    case parseTime defaultTimeLocale lambdaDateTimeFormat (T.unpack txt) of
+      Just dt → Right dt
+      Nothing → Left txt
+
+instance ToJSON LambdaDateTime where
+  toJSON = review $ _String ∘ _TextLambdaDateTime
+
+instance FromJSON LambdaDateTime where
+  parseJSON =
+    parserWithPrism "LambdaDateTime" $
+      _String ∘ _TextLambdaDateTime
+
+data EventSourceParameters
+  = EventSourceParameters
+  { _espInitialPositionInStream ∷ !(Maybe StreamPosition)
+  } deriving (Eq, Show)
+
+makeLenses ''EventSourceParameters
+
+instance FromJSON EventSourceParameters where
+  parseJSON =
+    withObject "EventSourceParameters" $ \o →
+      pure EventSourceParameters
+        ⊛ o .:? "InitialPositionInStream"
+
+instance ToJSON EventSourceParameters where
+  toJSON EventSourceParameters{..} = Object $
+    mempty
+      & at "InitialPositionInStream" .~ _espInitialPositionInStream ^? _Just ∘ to toJSON
+
+data EventSourceConfiguration
+  = EventSourceConfiguration
+  { _escBatchSize ∷ !(Maybe Int)
+  , _escEventSource ∷ !(Maybe Arn)
+  , _escFunctionName ∷ !(Maybe T.Text)
+  , _escIsActive ∷ !(Maybe Bool)
+  , _escLastModified ∷ !(Maybe LambdaDateTime)
+  , _escParameters ∷ !(Maybe EventSourceParameters)
+  , _escRole ∷ !(Maybe Arn)
+  , _escStatus ∷ !(Maybe EventSourceStatus)
+  , _escUuid ∷ !(Maybe LambdaUuid)
+  } deriving (Eq, Show)
+
+makeLenses ''EventSourceConfiguration
+
+-- | A kludge to get around incorrectly formatted JSON in AWS Lambda responses.
+--
+boolParserKludge
+  ∷ Object
+  → T.Text
+  → Parser Bool
+boolParserKludge o k = o .: k <|> (fromString =≪ o .: k)
+  where
+    fromString ∷ T.Text → Parser Bool
+    fromString = \case
+      "true" → return True
+      "false" → return False
+      _ → empty
+
+instance FromJSON EventSourceConfiguration where
+  parseJSON =
+    withObject "EventSourceConfiguration" $ \o →
+      pure EventSourceConfiguration
+        ⊛ o .:? "BatchSize"
+        ⊛ o .:? "EventSource"
+        ⊛ o .:? "FunctionName"
+        ⊛ optional (boolParserKludge o "IsActive")
+        ⊛ o .:? "LastModified"
+        ⊛ o .:? "Parameters"
+        ⊛ o .:? "Role"
+        ⊛ o .:? "Status"
+        ⊛ o .:? "UUID"
+
+newtype ConfigurationId
+  = ConfigurationId
+  { _cidText ∷ T.Text
+  } deriving (Eq, Show, ToJSON)
+
+cidText ∷ Getter ConfigurationId T.Text
+cidText = to _cidText
+
+instance FromJSON ConfigurationId where
+  parseJSON =
+    withText "ConfigurationId" $
+      pure ∘ ConfigurationId
+
+data FunctionMode
+  = FunctionModeEvent
+  deriving (Eq, Show)
+
+makePrisms ''FunctionMode
+
+instance FromJSON FunctionMode where
+  parseJSON =
+    parserWithPrism "FunctionMode" $
+      _String ∘ _TextFunctionMode
+
+functionModeToText
+  ∷ FunctionMode
+  → T.Text
+functionModeToText = \case
+  FunctionModeEvent → "event"
+
+_TextFunctionMode ∷ Prism' T.Text FunctionMode
+_TextFunctionMode =
+  prism functionModeToText $ \case
+    "event" → Right FunctionModeEvent
+    txt → Left txt
+
+data FunctionRuntime
+  = FunctionRuntimeNodeJs
+  deriving (Eq, Show)
+
+makePrisms ''FunctionRuntime
+
+instance FromJSON FunctionRuntime where
+  parseJSON =
+    parserWithPrism "FunctionRuntime" $
+      _String ∘ _TextFunctionRuntime
+
+functionRuntimeToText
+  ∷ FunctionRuntime
+  → T.Text
+functionRuntimeToText = \case
+  FunctionRuntimeNodeJs → "nodejs"
+
+_TextFunctionRuntime ∷ Prism' T.Text FunctionRuntime
+_TextFunctionRuntime =
+  prism functionRuntimeToText $ \case
+    "nodejs" → Right FunctionRuntimeNodeJs
+    txt → Left txt
+
+data FunctionConfiguration
+  = FunctionConfiguration
+  { _fcCodeSize ∷ !(Maybe Integer)
+  , _fcConfigurationId ∷ !(Maybe ConfigurationId)
+  , _fcDescription ∷ !(Maybe T.Text)
+  , _fcFunctionArn ∷ !(Maybe Arn)
+  , _fcFunctionName ∷ !(Maybe T.Text)
+  , _fcHandler ∷ !(Maybe T.Text)
+  , _fcLastModified ∷ !(Maybe LambdaDateTime)
+  , _fcMemorySize ∷ !(Maybe Int)
+  , _fcMode ∷ !(Maybe FunctionMode)
+  , _fcRole ∷ !(Maybe Arn)
+  , _fcRuntime ∷ !(Maybe FunctionRuntime)
+  , _fcTimeout ∷ !(Maybe Int)
+  } deriving (Eq, Show)
+
+makeLenses ''FunctionConfiguration
+
+-- | An empty 'FunctionConfiguration' object.
+--
+emptyFunctionConfiguration ∷ FunctionConfiguration
+emptyFunctionConfiguration = FunctionConfiguration
+  { _fcCodeSize = Nothing
+  , _fcConfigurationId = Nothing
+  , _fcDescription = Nothing
+  , _fcFunctionArn = Nothing
+  , _fcFunctionName = Nothing
+  , _fcHandler = Nothing
+  , _fcLastModified = Nothing
+  , _fcMemorySize = Nothing
+  , _fcMode = Nothing
+  , _fcRole = Nothing
+  , _fcRuntime = Nothing
+  , _fcTimeout = Nothing
+  }
+
+instance FromJSON FunctionConfiguration where
+  parseJSON =
+    withObject "FunctionConfiguration" $ \o → do
+      pure FunctionConfiguration
+        ⊛ o .:? "CodeSize"
+        ⊛ o .:? "ConfigurationId"
+        ⊛ o .:? "Description"
+        ⊛ o .:? "FunctionARN"
+        ⊛ o .:? "FunctionName"
+        ⊛ o .:? "Handler"
+        ⊛ o .:? "LastModified"
+        ⊛ o .:? "MemorySize"
+        ⊛ o .:? "Mode"
+        ⊛ o .:? "Role"
+        ⊛ o .:? "Runtime"
+        ⊛ o .:? "Timeout"
+
+
+data FunctionCodeLocation
+  = FunctionCodeLocation
+  { _fclLocation ∷ !(Maybe T.Text)
+    -- ^ The presigned URL you can use to download the function's @.zip@ file
+    -- that you previously uploaded. The URL is valid for up to 10 minutes.
+
+  , _fclRepositoryType ∷ !(Maybe T.Text)
+    -- ^ The repository from which you can download the function.
+  } deriving (Eq, Show)
+
+makeLenses ''FunctionCodeLocation
+
+instance FromJSON FunctionCodeLocation where
+  parseJSON =
+    withObject "FunctionCodeLocation" $ \o →
+      pure FunctionCodeLocation
+        ⊛ o .:? "Location"
+        ⊛ o .:? "RepositoryType"
