diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+    means each individual or legal entity that creates, contributes to
+    the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+    means the combination of the Contributions of others (if any) used
+    by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+    means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+    means Source Code Form to which the initial Contributor has attached
+    the notice in Exhibit A, the Executable Form of such Source Code
+    Form, and Modifications of such Source Code Form, in each case
+    including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+    means
+
+    (a) that the initial Contributor has attached the notice described
+        in Exhibit B to the Covered Software; or
+
+    (b) that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the
+        terms of a Secondary License.
+
+1.6. "Executable Form"
+    means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+    means a work that combines Covered Software with other material, in
+    a separate file or files, that is not Covered Software.
+
+1.8. "License"
+    means this document.
+
+1.9. "Licensable"
+    means having the right to grant, to the maximum extent possible,
+    whether at the time of the initial grant or subsequently, any and
+    all of the rights conveyed by this License.
+
+1.10. "Modifications"
+    means any of the following:
+
+    (a) any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered
+        Software; or
+
+    (b) any new file in Source Code Form that contains any Covered
+        Software.
+
+1.11. "Patent Claims" of a Contributor
+    means any patent claim(s), including without limitation, method,
+    process, and apparatus claims, in any patent Licensable by such
+    Contributor that would be infringed, but for the grant of the
+    License, by the making, using, selling, offering for sale, having
+    made, import, or transfer of either its Contributions or its
+    Contributor Version.
+
+1.12. "Secondary License"
+    means either the GNU General Public License, Version 2.0, the GNU
+    Lesser General Public License, Version 2.1, the GNU Affero General
+    Public License, Version 3.0, or any later versions of those
+    licenses.
+
+1.13. "Source Code Form"
+    means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+    means an individual or a legal entity exercising rights under this
+    License. For legal entities, "You" includes any entity that
+    controls, is controlled by, or is under common control with You. For
+    purposes of this definition, "control" means (a) the power, direct
+    or indirect, to cause the direction or management of such entity,
+    whether by contract or otherwise, or (b) ownership of more than
+    fifty percent (50%) of the outstanding shares or beneficial
+    ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+    Licensable by such Contributor to use, reproduce, make available,
+    modify, display, perform, distribute, and otherwise exploit its
+    Contributions, either on an unmodified basis, with Modifications, or
+    as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+    for sale, have made, import, and otherwise transfer either its
+    Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+    or
+
+(b) for infringements caused by: (i) Your and any other third party's
+    modifications of Covered Software, or (ii) the combination of its
+    Contributions with other software (except as part of its Contributor
+    Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+    its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+    Form, as described in Section 3.1, and You must inform recipients of
+    the Executable Form how they can obtain a copy of such Source Code
+    Form by reasonable means in a timely manner, at a charge no more
+    than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+    License, or sublicense it under different terms, provided that the
+    license for the Executable Form does not attempt to limit or alter
+    the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+*                                                                      *
+*  6. Disclaimer of Warranty                                           *
+*  -------------------------                                           *
+*                                                                      *
+*  Covered Software is provided under this License on an "as is"       *
+*  basis, without warranty of any kind, either expressed, implied, or  *
+*  statutory, including, without limitation, warranties that the       *
+*  Covered Software is free of defects, merchantable, fit for a        *
+*  particular purpose or non-infringing. The entire risk as to the     *
+*  quality and performance of the Covered Software is with You.        *
+*  Should any Covered Software prove defective in any respect, You     *
+*  (not any Contributor) assume the cost of any necessary servicing,   *
+*  repair, or correction. This disclaimer of warranty constitutes an   *
+*  essential part of this License. No use of any Covered Software is   *
+*  authorized under this License except under this disclaimer.         *
+*                                                                      *
+************************************************************************
+
+************************************************************************
+*                                                                      *
+*  7. Limitation of Liability                                          *
+*  --------------------------                                          *
+*                                                                      *
+*  Under no circumstances and under no legal theory, whether tort      *
+*  (including negligence), contract, or otherwise, shall any           *
+*  Contributor, or anyone who distributes Covered Software as          *
+*  permitted above, be liable to You for any direct, indirect,         *
+*  special, incidental, or consequential damages of any character      *
+*  including, without limitation, damages for lost profits, loss of    *
+*  goodwill, work stoppage, computer failure or malfunction, or any    *
+*  and all other commercial damages or losses, even if such party      *
+*  shall have been informed of the possibility of such damages. This   *
+*  limitation of liability shall not apply to liability for death or   *
+*  personal injury resulting from such party's negligence to the       *
+*  extent applicable law prohibits such limitation. Some               *
+*  jurisdictions do not allow the exclusion or limitation of           *
+*  incidental or consequential damages, so this exclusion and          *
+*  limitation may not apply to You.                                    *
+*                                                                      *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+  This Source Code Form is "Incompatible With Secondary Licenses", as
+  defined by the Mozilla Public License, v. 2.0.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,26 @@
+# Amazon DynamoDB SDK
+
+> _Warning:_ This is an experimental preview release which is still under heavy development and not intended for public consumption, _caveat emptor_!
+
+* [description](#description)
+* [Contribute](#contribute)
+* [Licence](#licence)
+
+## Description
+
+Amazon DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability. You can use Amazon DynamoDB to create a database table that can store and retrieve any amount of data, and serve any level of request traffic. Amazon DynamoDB automatically spreads the data and traffic for the table over a sufficient number of servers to handle the request capacity specified by the customer and the amount of data stored, while maintaining consistent and fast performance.
+
+Documentation is available via [Hackage](http://hackage.haskell.org/package/amazonka-dynamodb)
+and [AWS API Reference](http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/Welcome.html).
+
+
+## Contribute
+
+For any problems, comments, or feedback please create an issue [here on GitHub](https://github.com/brendanhay/amazonka/issues).
+
+> _Note:_ this library is an auto-generated Haskell package. Please see `amazonka-gen` for more information.
+
+
+## Licence
+
+`amazonka-dynamodb` is released under the [Mozilla Public License Version 2.0](http://www.mozilla.org/MPL/).
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/amazonka-dynamodb.cabal b/amazonka-dynamodb.cabal
new file mode 100644
--- /dev/null
+++ b/amazonka-dynamodb.cabal
@@ -0,0 +1,61 @@
+name:                  amazonka-dynamodb
+version:               0.0.0
+synopsis:              Amazon DynamoDB SDK.
+homepage:              https://github.com/brendanhay/amazonka
+license:               OtherLicense
+license-file:          LICENSE
+author:                Brendan Hay
+maintainer:            Brendan Hay <brendan.g.hay@gmail.com>
+copyright:             Copyright (c) 2013-2014 Brendan Hay
+category:              Network, AWS, Cloud
+build-type:            Simple
+extra-source-files:    README.md
+cabal-version:         >= 1.10
+
+description:
+    Amazon DynamoDB is a fully managed NoSQL database service that provides
+    fast and predictable performance with seamless scalability. You can use
+    Amazon DynamoDB to create a database table that can store and retrieve
+    any amount of data, and serve any level of request traffic. Amazon
+    DynamoDB automatically spreads the data and traffic for the table over
+    a sufficient number of servers to handle the request capacity specified
+    by the customer and the amount of data stored, while maintaining
+    consistent and fast performance.
+    .
+    /See:/ <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/Welcome.html AWS API Reference>
+    .
+    /Warning:/ This is an experimental preview release which is still under
+    heavy development and not intended for public consumption, caveat emptor!
+
+source-repository head
+    type:     git
+    location: git://github.com/brendanhay/amazonka.git
+
+library
+    default-language:  Haskell2010
+    hs-source-dirs:    src gen
+
+    ghc-options:       -Wall
+
+    exposed-modules:
+          Network.AWS.DynamoDB
+        , Network.AWS.DynamoDB.BatchGetItem
+        , Network.AWS.DynamoDB.BatchWriteItem
+        , Network.AWS.DynamoDB.CreateTable
+        , Network.AWS.DynamoDB.DeleteItem
+        , Network.AWS.DynamoDB.DeleteTable
+        , Network.AWS.DynamoDB.DescribeTable
+        , Network.AWS.DynamoDB.GetItem
+        , Network.AWS.DynamoDB.ListTables
+        , Network.AWS.DynamoDB.PutItem
+        , Network.AWS.DynamoDB.Query
+        , Network.AWS.DynamoDB.Scan
+        , Network.AWS.DynamoDB.Types
+        , Network.AWS.DynamoDB.UpdateItem
+        , Network.AWS.DynamoDB.UpdateTable
+
+    other-modules:
+
+    build-depends:
+          amazonka-core
+        , base          >= 4.7 && < 5
diff --git a/gen/Network/AWS/DynamoDB.hs b/gen/Network/AWS/DynamoDB.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB.hs
@@ -0,0 +1,49 @@
+-- Module      : Network.AWS.DynamoDB
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Amazon DynamoDB is a fully managed NoSQL database service that provides
+-- fast and predictable performance with seamless scalability. You can use
+-- Amazon DynamoDB to create a database table that can store and retrieve any
+-- amount of data, and serve any level of request traffic. Amazon DynamoDB
+-- automatically spreads the data and traffic for the table over a sufficient
+-- number of servers to handle the request capacity specified by the customer
+-- and the amount of data stored, while maintaining consistent and fast
+-- performance.
+module Network.AWS.DynamoDB
+    ( module Network.AWS.DynamoDB.BatchGetItem
+    , module Network.AWS.DynamoDB.BatchWriteItem
+    , module Network.AWS.DynamoDB.CreateTable
+    , module Network.AWS.DynamoDB.DeleteItem
+    , module Network.AWS.DynamoDB.DeleteTable
+    , module Network.AWS.DynamoDB.DescribeTable
+    , module Network.AWS.DynamoDB.GetItem
+    , module Network.AWS.DynamoDB.ListTables
+    , module Network.AWS.DynamoDB.PutItem
+    , module Network.AWS.DynamoDB.Query
+    , module Network.AWS.DynamoDB.Scan
+    , module Network.AWS.DynamoDB.Types
+    , module Network.AWS.DynamoDB.UpdateItem
+    , module Network.AWS.DynamoDB.UpdateTable
+    ) where
+
+import Network.AWS.DynamoDB.BatchGetItem
+import Network.AWS.DynamoDB.BatchWriteItem
+import Network.AWS.DynamoDB.CreateTable
+import Network.AWS.DynamoDB.DeleteItem
+import Network.AWS.DynamoDB.DeleteTable
+import Network.AWS.DynamoDB.DescribeTable
+import Network.AWS.DynamoDB.GetItem
+import Network.AWS.DynamoDB.ListTables
+import Network.AWS.DynamoDB.PutItem
+import Network.AWS.DynamoDB.Query
+import Network.AWS.DynamoDB.Scan
+import Network.AWS.DynamoDB.Types
+import Network.AWS.DynamoDB.UpdateItem
+import Network.AWS.DynamoDB.UpdateTable
diff --git a/gen/Network/AWS/DynamoDB/BatchGetItem.hs b/gen/Network/AWS/DynamoDB/BatchGetItem.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/BatchGetItem.hs
@@ -0,0 +1,209 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.BatchGetItem
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | The BatchGetItem operation returns the attributes of one or more items from
+-- one or more tables. You identify requested items by primary key. A single
+-- operation can retrieve up to 16 MB of data, which can contain as many as
+-- 100 items. BatchGetItem will return a partial result if the response size
+-- limit is exceeded, the table's provisioned throughput is exceeded, or an
+-- internal processing failure occurs. If a partial result is returned, the
+-- operation returns a value for UnprocessedKeys. You can use this value to
+-- retry the operation starting with the next item to get. For example, if you
+-- ask to retrieve 100 items, but each individual item is 300 KB in size, the
+-- system returns 52 items (so as not to exceed the 16 MB limit). It also
+-- returns an appropriate UnprocessedKeys value so you can get the next page
+-- of results. If desired, your application can include its own logic to
+-- assemble the pages of results into one data set. If none of the items can
+-- be processed due to insufficient provisioned throughput on all of the
+-- tables in the request, then BatchGetItem will return a
+-- ProvisionedThroughputExceededException. If at least one of the items is
+-- successfully processed, then BatchGetItem completes successfully, while
+-- returning the keys of the unread items in UnprocessedKeys. If DynamoDB
+-- returns any unprocessed items, you should retry the batch operation on
+-- those items. However, we strongly recommend that you use an exponential
+-- backoff algorithm. If you retry the batch operation immediately, the
+-- underlying read or write requests can still fail due to throttling on the
+-- individual tables. If you delay the batch operation using exponential
+-- backoff, the individual requests in the batch are much more likely to
+-- succeed. For more information, go to Batch Operations and Error Handling in
+-- the Amazon DynamoDB Developer Guide. By default, BatchGetItem performs
+-- eventually consistent reads on every table in the request. If you want
+-- strongly consistent reads instead, you can set ConsistentRead to true for
+-- any or all tables. In order to minimize response latency, BatchGetItem
+-- retrieves items in parallel. When designing your application, keep in mind
+-- that DynamoDB does not return attributes in any particular order. To help
+-- parse the response by item, include the primary key values for the items in
+-- your request in the AttributesToGet parameter. If a requested item does not
+-- exist, it is not returned in the result. Requests for nonexistent items
+-- consume the minimum read capacity units according to the type of read. For
+-- more information, see Capacity Units Calculations in the Amazon DynamoDB
+-- Developer Guide.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html>
+module Network.AWS.DynamoDB.BatchGetItem
+    (
+    -- * Request
+      BatchGetItem
+    -- ** Request constructor
+    , batchGetItem
+    -- ** Request lenses
+    , bgiRequestItems
+    , bgiReturnConsumedCapacity
+
+    -- * Response
+    , BatchGetItemResponse
+    -- ** Response constructor
+    , batchGetItemResponse
+    -- ** Response lenses
+    , bgirConsumedCapacity
+    , bgirResponses
+    , bgirUnprocessedKeys
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+data BatchGetItem = BatchGetItem
+    { _bgiRequestItems           :: Map Text KeysAndAttributes
+    , _bgiReturnConsumedCapacity :: Maybe Text
+    } deriving (Eq, Show)
+
+-- | 'BatchGetItem' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'bgiRequestItems' @::@ 'HashMap' 'Text' 'KeysAndAttributes'
+--
+-- * 'bgiReturnConsumedCapacity' @::@ 'Maybe' 'Text'
+--
+batchGetItem :: BatchGetItem
+batchGetItem = BatchGetItem
+    { _bgiRequestItems           = mempty
+    , _bgiReturnConsumedCapacity = Nothing
+    }
+
+-- | A map of one or more table names and, for each table, the corresponding
+-- primary keys for the items to retrieve. Each table name can be invoked
+-- only once. Each element in the map consists of the following: Keys - An
+-- array of primary key attribute values that define specific items in the
+-- table. For each primary key, you must provide all of the key attributes.
+-- For example, with a hash type primary key, you only need to specify the
+-- hash attribute. For a hash-and-range type primary key, you must specify
+-- both the hash attribute and the range attribute. AttributesToGet - One or
+-- more attributes to be retrieved from the table. By default, all
+-- attributes are returned. If a specified attribute is not found, it does
+-- not appear in the result. Note that AttributesToGet has no effect on
+-- provisioned throughput consumption. DynamoDB determines capacity units
+-- consumed based on item size, not on the amount of data that is returned
+-- to an application. ConsistentRead - If true, a strongly consistent read
+-- is used; if false (the default), an eventually consistent read is used.
+bgiRequestItems :: Lens' BatchGetItem (HashMap Text KeysAndAttributes)
+bgiRequestItems = lens _bgiRequestItems (\s a -> s { _bgiRequestItems = a }) . _Map
+
+bgiReturnConsumedCapacity :: Lens' BatchGetItem (Maybe Text)
+bgiReturnConsumedCapacity =
+    lens _bgiReturnConsumedCapacity
+        (\s a -> s { _bgiReturnConsumedCapacity = a })
+
+data BatchGetItemResponse = BatchGetItemResponse
+    { _bgirConsumedCapacity :: List "ConsumedCapacity" ConsumedCapacity
+    , _bgirResponses        :: Map Text (List "Items" (Map Text AttributeValue))
+    , _bgirUnprocessedKeys  :: Map Text KeysAndAttributes
+    } deriving (Eq, Show)
+
+-- | 'BatchGetItemResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'bgirConsumedCapacity' @::@ ['ConsumedCapacity']
+--
+-- * 'bgirResponses' @::@ 'HashMap' 'Text' ['HashMap' 'Text' 'AttributeValue']
+--
+-- * 'bgirUnprocessedKeys' @::@ 'HashMap' 'Text' 'KeysAndAttributes'
+--
+batchGetItemResponse :: BatchGetItemResponse
+batchGetItemResponse = BatchGetItemResponse
+    { _bgirResponses        = mempty
+    , _bgirUnprocessedKeys  = mempty
+    , _bgirConsumedCapacity = mempty
+    }
+
+-- | The write capacity units consumed by the operation. Each element consists
+-- of: TableName - The table that consumed the provisioned throughput.
+-- CapacityUnits - The total number of capacity units consumed.
+bgirConsumedCapacity :: Lens' BatchGetItemResponse [ConsumedCapacity]
+bgirConsumedCapacity =
+    lens _bgirConsumedCapacity (\s a -> s { _bgirConsumedCapacity = a })
+        . _List
+
+-- | A map of table name to a list of items. Each object in Responses consists
+-- of a table name, along with a map of attribute data consisting of the
+-- data type and attribute value.
+bgirResponses :: Lens' BatchGetItemResponse (HashMap Text [HashMap Text AttributeValue])
+bgirResponses = lens _bgirResponses (\s a -> s { _bgirResponses = a }) . _Map
+
+-- | A map of tables and their respective keys that were not processed with
+-- the current response. The UnprocessedKeys value is in the same form as
+-- RequestItems, so the value can be provided directly to a subsequent
+-- BatchGetItem operation. For more information, see RequestItems in the
+-- Request Parameters section. Each element consists of: Keys - An array of
+-- primary key attribute values that define specific items in the table.
+-- AttributesToGet - One or more attributes to be retrieved from the table
+-- or index. By default, all attributes are returned. If a specified
+-- attribute is not found, it does not appear in the result. ConsistentRead
+-- - The consistency of a read operation. If set to true, then a strongly
+-- consistent read is used; otherwise, an eventually consistent read is
+-- used. If there are no unprocessed keys remaining, the response contains
+-- an empty UnprocessedKeys map.
+bgirUnprocessedKeys :: Lens' BatchGetItemResponse (HashMap Text KeysAndAttributes)
+bgirUnprocessedKeys =
+    lens _bgirUnprocessedKeys (\s a -> s { _bgirUnprocessedKeys = a })
+        . _Map
+
+instance ToPath BatchGetItem where
+    toPath = const "/"
+
+instance ToQuery BatchGetItem where
+    toQuery = const mempty
+
+instance ToHeaders BatchGetItem
+
+instance ToJSON BatchGetItem where
+    toJSON BatchGetItem{..} = object
+        [ "RequestItems"           .= _bgiRequestItems
+        , "ReturnConsumedCapacity" .= _bgiReturnConsumedCapacity
+        ]
+
+instance AWSRequest BatchGetItem where
+    type Sv BatchGetItem = DynamoDB
+    type Rs BatchGetItem = BatchGetItemResponse
+
+    request  = post "BatchGetItem"
+    response = jsonResponse
+
+instance FromJSON BatchGetItemResponse where
+    parseJSON = withObject "BatchGetItemResponse" $ \o -> BatchGetItemResponse
+        <$> o .:  "ConsumedCapacity"
+        <*> o .:  "Responses"
+        <*> o .:  "UnprocessedKeys"
diff --git a/gen/Network/AWS/DynamoDB/BatchWriteItem.hs b/gen/Network/AWS/DynamoDB/BatchWriteItem.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/BatchWriteItem.hs
@@ -0,0 +1,263 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.BatchWriteItem
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | The BatchWriteItem operation puts or deletes multiple items in one or more
+-- tables. A single call to BatchWriteItem can write up to 16 MB of data,
+-- which can comprise as many as 25 put or delete requests. Individual items
+-- to be written can be as large as 400 KB. The individual PutItem and
+-- DeleteItem operations specified in BatchWriteItem are atomic; however
+-- BatchWriteItem as a whole is not. If any requested operations fail because
+-- the table's provisioned throughput is exceeded or an internal processing
+-- failure occurs, the failed operations are returned in the UnprocessedItems
+-- response parameter. You can investigate and optionally resend the requests.
+-- Typically, you would call BatchWriteItem in a loop. Each iteration would
+-- check for unprocessed items and submit a new BatchWriteItem request with
+-- those unprocessed items until all items have been processed. Note that if
+-- none of the items can be processed due to insufficient provisioned
+-- throughput on all of the tables in the request, then BatchWriteItem will
+-- return a ProvisionedThroughputExceededException. If DynamoDB returns any
+-- unprocessed items, you should retry the batch operation on those items.
+-- However, we strongly recommend that you use an exponential backoff
+-- algorithm. If you retry the batch operation immediately, the underlying
+-- read or write requests can still fail due to throttling on the individual
+-- tables. If you delay the batch operation using exponential backoff, the
+-- individual requests in the batch are much more likely to succeed. For more
+-- information, go to Batch Operations and Error Handling in the Amazon
+-- DynamoDB Developer Guide. With BatchWriteItem, you can efficiently write or
+-- delete large amounts of data, such as from Amazon Elastic MapReduce (EMR),
+-- or copy data from another database into DynamoDB. In order to improve
+-- performance with these large-scale operations, BatchWriteItem does not
+-- behave in the same way as individual PutItem and DeleteItem calls would For
+-- example, you cannot specify conditions on individual put and delete
+-- requests, and BatchWriteItem does not return deleted items in the response.
+-- If you use a programming language that supports concurrency, such as Java,
+-- you can use threads to write items in parallel. Your application must
+-- include the necessary logic to manage the threads. With languages that
+-- don't support threading, such as PHP, you must update or delete the
+-- specified items one at a time. In both situations, BatchWriteItem provides
+-- an alternative where the API performs the specified put and delete
+-- operations in parallel, giving you the power of the thread pool approach
+-- without having to introduce complexity into your application. Parallel
+-- processing reduces latency, but each specified put and delete request
+-- consumes the same number of write capacity units whether it is processed in
+-- parallel or not. Delete operations on nonexistent items consume one write
+-- capacity unit. If one or more of the following is true, DynamoDB rejects
+-- the entire batch write operation: One or more tables specified in the
+-- BatchWriteItem request does not exist. Primary key attributes specified on
+-- an item in the request do not match those in the corresponding table's
+-- primary key schema. You try to perform multiple operations on the same item
+-- in the same BatchWriteItem request. For example, you cannot put and delete
+-- the same item in the same BatchWriteItem request. There are more than 25
+-- requests in the batch. Any individual item in a batch exceeds 400 KB. The
+-- total request size exceeds 16 MB.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html>
+module Network.AWS.DynamoDB.BatchWriteItem
+    (
+    -- * Request
+      BatchWriteItem
+    -- ** Request constructor
+    , batchWriteItem
+    -- ** Request lenses
+    , bwiRequestItems
+    , bwiReturnConsumedCapacity
+    , bwiReturnItemCollectionMetrics
+
+    -- * Response
+    , BatchWriteItemResponse
+    -- ** Response constructor
+    , batchWriteItemResponse
+    -- ** Response lenses
+    , bwirConsumedCapacity
+    , bwirItemCollectionMetrics
+    , bwirUnprocessedItems
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+data BatchWriteItem = BatchWriteItem
+    { _bwiRequestItems                :: Map Text (List1 "RequestItems" WriteRequest)
+    , _bwiReturnConsumedCapacity      :: Maybe Text
+    , _bwiReturnItemCollectionMetrics :: Maybe Text
+    } deriving (Eq, Show)
+
+-- | 'BatchWriteItem' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'bwiRequestItems' @::@ 'HashMap' 'Text' ('NonEmpty' 'WriteRequest')
+--
+-- * 'bwiReturnConsumedCapacity' @::@ 'Maybe' 'Text'
+--
+-- * 'bwiReturnItemCollectionMetrics' @::@ 'Maybe' 'Text'
+--
+batchWriteItem :: BatchWriteItem
+batchWriteItem = BatchWriteItem
+    { _bwiRequestItems                = mempty
+    , _bwiReturnConsumedCapacity      = Nothing
+    , _bwiReturnItemCollectionMetrics = Nothing
+    }
+
+-- | A map of one or more table names and, for each table, a list of
+-- operations to be performed (DeleteRequest or PutRequest). Each element in
+-- the map consists of the following: DeleteRequest - Perform a DeleteItem
+-- operation on the specified item. The item to be deleted is identified by
+-- a Key subelement: Key - A map of primary key attribute values that
+-- uniquely identify the ! item. Each entry in this map consists of an
+-- attribute name and an attribute value. For each primary key, you must
+-- provide all of the key attributes. For example, with a hash type primary
+-- key, you only need to specify the hash attribute. For a hash-and-range
+-- type primary key, you must specify both the hash attribute and the range
+-- attribute. PutRequest - Perform a PutItem operation on the specified
+-- item. The item to be put is identified by an Item subelement: Item - A
+-- map of attributes and their values. Each entry in this map consists of an
+-- attribute name and an attribute value. Attribute values must not be null;
+-- string and binary type attributes must have lengths greater than zero;
+-- and set type attributes must not be empty. Requests that contain empty
+-- values will be rejected with a ValidationException exception. If you
+-- specify any attributes that are part of an index key, then the data types
+-- for those attributes must match those of the schema in the table's
+-- attribute definition.
+bwiRequestItems :: Lens' BatchWriteItem (HashMap Text (NonEmpty WriteRequest))
+bwiRequestItems = lens _bwiRequestItems (\s a -> s { _bwiRequestItems = a }) . _Map
+
+bwiReturnConsumedCapacity :: Lens' BatchWriteItem (Maybe Text)
+bwiReturnConsumedCapacity =
+    lens _bwiReturnConsumedCapacity
+        (\s a -> s { _bwiReturnConsumedCapacity = a })
+
+-- | A value that if set to SIZE, the response includes statistics about item
+-- collections, if any, that were modified during the operation are returned
+-- in the response. If set to NONE (the default), no statistics are
+-- returned.
+bwiReturnItemCollectionMetrics :: Lens' BatchWriteItem (Maybe Text)
+bwiReturnItemCollectionMetrics =
+    lens _bwiReturnItemCollectionMetrics
+        (\s a -> s { _bwiReturnItemCollectionMetrics = a })
+
+data BatchWriteItemResponse = BatchWriteItemResponse
+    { _bwirConsumedCapacity      :: List "ConsumedCapacity" ConsumedCapacity
+    , _bwirItemCollectionMetrics :: Map Text (List "ItemCollectionMetrics" ItemCollectionMetrics)
+    , _bwirUnprocessedItems      :: Map Text (List1 "RequestItems" WriteRequest)
+    } deriving (Eq, Show)
+
+-- | 'BatchWriteItemResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'bwirConsumedCapacity' @::@ ['ConsumedCapacity']
+--
+-- * 'bwirItemCollectionMetrics' @::@ 'HashMap' 'Text' ['ItemCollectionMetrics']
+--
+-- * 'bwirUnprocessedItems' @::@ 'HashMap' 'Text' ('NonEmpty' 'WriteRequest')
+--
+batchWriteItemResponse :: BatchWriteItemResponse
+batchWriteItemResponse = BatchWriteItemResponse
+    { _bwirUnprocessedItems      = mempty
+    , _bwirItemCollectionMetrics = mempty
+    , _bwirConsumedCapacity      = mempty
+    }
+
+-- | The capacity units consumed by the operation. Each element consists of:
+-- TableName - The table that consumed the provisioned throughput.
+-- CapacityUnits - The total number of capacity units consumed.
+bwirConsumedCapacity :: Lens' BatchWriteItemResponse [ConsumedCapacity]
+bwirConsumedCapacity =
+    lens _bwirConsumedCapacity (\s a -> s { _bwirConsumedCapacity = a })
+        . _List
+
+-- | A list of tables that were processed by BatchWriteItem and, for each
+-- table, information about any item collections that were affected by
+-- individual DeleteItem or PutItem operations. Each entry consists of the
+-- following subelements: ItemCollectionKey - The hash key value of the item
+-- collection. This is the same as the hash key of the item.
+-- SizeEstimateRange - An estimate of item collection size, expressed in GB.
+-- This is a two-element array containing a lower bound and an upper bound
+-- for the estimate. The estimate includes the size of all the items in the
+-- table, plus the size of all attributes projected into all of the local
+-- secondary indexes on the table. Use this estimate to measure whether a
+-- local secondary index is approaching its size limit. The estimate is
+-- subject to change over time; therefore, do not rely on the precision or
+-- accuracy of the estimate.
+bwirItemCollectionMetrics :: Lens' BatchWriteItemResponse (HashMap Text [ItemCollectionMetrics])
+bwirItemCollectionMetrics =
+    lens _bwirItemCollectionMetrics
+        (\s a -> s { _bwirItemCollectionMetrics = a })
+            . _Map
+
+-- | A map of tables and requests against those tables that were not
+-- processed. The UnprocessedItems value is in the same form as
+-- RequestItems, so you can provide this value directly to a subsequent
+-- BatchGetItem operation. For more information, see RequestItems in the
+-- Request Parameters section. Each UnprocessedItems entry consists of a
+-- table name and, for that table, a list of operations to perform
+-- (DeleteRequest or PutRequest). DeleteRequest - Perform a DeleteItem
+-- operation on the specified item. The item to be deleted is identified by
+-- a Key subelement: Key - A map of primary key attribute values that
+-- uniquely identify the item. Each entry in this map consists of an
+-- attribute name and an attribute value. PutRequest - Perform a PutItem
+-- operation on the specified item. The item to be put is identified by an
+-- Item subelement: Item - A map of attributes and their values. Each entry
+-- in this map consists of an attribute name and an attribute value.
+-- Attribute values must not be null; string and binary type attributes must
+-- have lengths greater than zero; and set type attributes must not be
+-- empty. Requests that contain empty values will be rejected with a
+-- ValidationException exception. If you specify any attributes that are
+-- part of an index key, then the data types for those attributes must match
+-- those of the schema in the table's attribute definition. If there are no
+-- unprocessed items remaining, the response contains an empty
+-- UnprocessedItems map.
+bwirUnprocessedItems :: Lens' BatchWriteItemResponse (HashMap Text (NonEmpty WriteRequest))
+bwirUnprocessedItems =
+    lens _bwirUnprocessedItems (\s a -> s { _bwirUnprocessedItems = a })
+        . _Map
+
+instance ToPath BatchWriteItem where
+    toPath = const "/"
+
+instance ToQuery BatchWriteItem where
+    toQuery = const mempty
+
+instance ToHeaders BatchWriteItem
+
+instance ToJSON BatchWriteItem where
+    toJSON BatchWriteItem{..} = object
+        [ "RequestItems"                .= _bwiRequestItems
+        , "ReturnConsumedCapacity"      .= _bwiReturnConsumedCapacity
+        , "ReturnItemCollectionMetrics" .= _bwiReturnItemCollectionMetrics
+        ]
+
+instance AWSRequest BatchWriteItem where
+    type Sv BatchWriteItem = DynamoDB
+    type Rs BatchWriteItem = BatchWriteItemResponse
+
+    request  = post "BatchWriteItem"
+    response = jsonResponse
+
+instance FromJSON BatchWriteItemResponse where
+    parseJSON = withObject "BatchWriteItemResponse" $ \o -> BatchWriteItemResponse
+        <$> o .:  "ConsumedCapacity"
+        <*> o .:  "ItemCollectionMetrics"
+        <*> o .:  "UnprocessedItems"
diff --git a/gen/Network/AWS/DynamoDB/CreateTable.hs b/gen/Network/AWS/DynamoDB/CreateTable.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/CreateTable.hs
@@ -0,0 +1,229 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.CreateTable
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | The CreateTable operation adds a new table to your account. In an AWS
+-- account, table names must be unique within each region. That is, you can
+-- have two tables with same name if you create the tables in different
+-- regions. CreateTable is an asynchronous operation. Upon receiving a
+-- CreateTable request, DynamoDB immediately returns a response with a
+-- TableStatus of CREATING. After the table is created, DynamoDB sets the
+-- TableStatus to ACTIVE. You can perform read and write operations only on an
+-- ACTIVE table. If you want to create multiple tables with secondary indexes
+-- on them, you must create them sequentially. Only one table with secondary
+-- indexes can be in the CREATING state at any given time. You can use the
+-- DescribeTable API to check the table status.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html>
+module Network.AWS.DynamoDB.CreateTable
+    (
+    -- * Request
+      CreateTable
+    -- ** Request constructor
+    , createTable
+    -- ** Request lenses
+    , ctAttributeDefinitions
+    , ctGlobalSecondaryIndexes
+    , ctKeySchema
+    , ctLocalSecondaryIndexes
+    , ctProvisionedThroughput
+    , ctTableName
+
+    -- * Response
+    , CreateTableResponse
+    -- ** Response constructor
+    , createTableResponse
+    -- ** Response lenses
+    , ctrTableDescription
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+data CreateTable = CreateTable
+    { _ctAttributeDefinitions   :: List "AttributeDefinitions" AttributeDefinition
+    , _ctGlobalSecondaryIndexes :: List "GlobalSecondaryIndexes" GlobalSecondaryIndex
+    , _ctKeySchema              :: List1 "KeySchema" KeySchemaElement
+    , _ctLocalSecondaryIndexes  :: List "LocalSecondaryIndexes" LocalSecondaryIndex
+    , _ctProvisionedThroughput  :: ProvisionedThroughput
+    , _ctTableName              :: Text
+    } deriving (Eq, Show)
+
+-- | 'CreateTable' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'ctAttributeDefinitions' @::@ ['AttributeDefinition']
+--
+-- * 'ctGlobalSecondaryIndexes' @::@ ['GlobalSecondaryIndex']
+--
+-- * 'ctKeySchema' @::@ 'NonEmpty' 'KeySchemaElement'
+--
+-- * 'ctLocalSecondaryIndexes' @::@ ['LocalSecondaryIndex']
+--
+-- * 'ctProvisionedThroughput' @::@ 'ProvisionedThroughput'
+--
+-- * 'ctTableName' @::@ 'Text'
+--
+createTable :: Text -- ^ 'ctTableName'
+            -> NonEmpty KeySchemaElement -- ^ 'ctKeySchema'
+            -> ProvisionedThroughput -- ^ 'ctProvisionedThroughput'
+            -> CreateTable
+createTable p1 p2 p3 = CreateTable
+    { _ctTableName              = p1
+    , _ctKeySchema              = withIso _List1 (const id) p2
+    , _ctProvisionedThroughput  = p3
+    , _ctAttributeDefinitions   = mempty
+    , _ctLocalSecondaryIndexes  = mempty
+    , _ctGlobalSecondaryIndexes = mempty
+    }
+
+-- | An array of attributes that describe the key schema for the table and
+-- indexes.
+ctAttributeDefinitions :: Lens' CreateTable [AttributeDefinition]
+ctAttributeDefinitions =
+    lens _ctAttributeDefinitions (\s a -> s { _ctAttributeDefinitions = a })
+        . _List
+
+-- | One or more global secondary indexes (the maximum is five) to be created
+-- on the table. Each global secondary index in the array includes the
+-- following: IndexName - The name of the global secondary index. Must be
+-- unique only for this table. KeySchema - Specifies the key schema for the
+-- global secondary index. Projection - Specifies attributes that are copied
+-- (projected) from the table into the index. These are in addition to the
+-- primary key attributes and index key attributes, which are automatically
+-- projected. Each attribute specification is composed of: ProjectionType -
+-- One of the following: KEYS_ONLY - Only the index and primary keys are
+-- projected into the index. INCLUDE - Only the specified table attributes
+-- are projected into the index. The list of projected attributes are in
+-- NonKeyAttributes. ALL - All of the table attributes are projected into
+-- the index. NonKeyAttributes - A list of one or more non-key attribute
+-- names that are projected into the secondary index. The total count of
+-- attributes specified in NonKeyAttributes, summed across all of the
+-- secondary indexes, must not exceed 20. If you project the same attribute
+-- into two different indexes, this counts as two distinct attributes when
+-- determining the total. ProvisionedThroughput - The provisioned throughput
+-- settings for the global secondary index, consisting of read and write
+-- capacity units.
+ctGlobalSecondaryIndexes :: Lens' CreateTable [GlobalSecondaryIndex]
+ctGlobalSecondaryIndexes =
+    lens _ctGlobalSecondaryIndexes
+        (\s a -> s { _ctGlobalSecondaryIndexes = a })
+            . _List
+
+-- | Specifies the attributes that make up the primary key for a table or an
+-- index. The attributes in KeySchema must also be defined in the
+-- AttributeDefinitions array. For more information, see Data Model in the
+-- Amazon DynamoDB Developer Guide. Each KeySchemaElement in the array is
+-- composed of: AttributeName - The name of this key attribute. KeyType -
+-- Determines whether the key attribute is HASH or RANGE. For a primary key
+-- that consists of a hash attribute, you must specify exactly one element
+-- with a KeyType of HASH. For a primary key that consists of hash and range
+-- attributes, you must specify exactly two elements, in this order: The
+-- first element must have a KeyType of HASH, and the second element must
+-- have a KeyType of RANGE. For more information, see Specifying the Primary
+-- Key in the Amazon DynamoDB Developer Guide.
+ctKeySchema :: Lens' CreateTable (NonEmpty KeySchemaElement)
+ctKeySchema = lens _ctKeySchema (\s a -> s { _ctKeySchema = a }) . _List1
+
+-- | One or more local secondary indexes (the maximum is five) to be created
+-- on the table. Each index is scoped to a given hash key value. There is a
+-- 10 GB size limit per hash key; otherwise, the size of a local secondary
+-- index is unconstrained. Each local secondary index in the array includes
+-- the following: IndexName - The name of the local secondary index. Must be
+-- unique only for this table. KeySchema - Specifies the key schema for the
+-- local secondary index. The key schema must begin with the same hash key
+-- attribute as the table. Projection - Specifies attributes that are copied
+-- (projected) from the table into the index. These are in addition to the
+-- primary key attributes and index key attributes, which are automatically
+-- projected. Each attribute specification is composed of: ProjectionType -
+-- One of the following: KEYS_ONLY - Only the index and primary keys are
+-- projected into the index. INCLUDE - Only the specified table attributes
+-- are projected into the index. The list of projected attributes are in
+-- NonKeyAttributes. ALL - All of the table attributes are projected into
+-- the index. NonKeyAttributes - A list of one or more non-key attribute
+-- names that are projected into the secondary index. The total count of
+-- attributes specified in NonKeyAttributes, summed across all of the
+-- secondary indexes, must not exceed 20. If you project the same attribute
+-- into two different indexes, this counts as two distinct attributes when
+-- determining the total.
+ctLocalSecondaryIndexes :: Lens' CreateTable [LocalSecondaryIndex]
+ctLocalSecondaryIndexes =
+    lens _ctLocalSecondaryIndexes (\s a -> s { _ctLocalSecondaryIndexes = a })
+        . _List
+
+ctProvisionedThroughput :: Lens' CreateTable ProvisionedThroughput
+ctProvisionedThroughput =
+    lens _ctProvisionedThroughput (\s a -> s { _ctProvisionedThroughput = a })
+
+-- | The name of the table to create.
+ctTableName :: Lens' CreateTable Text
+ctTableName = lens _ctTableName (\s a -> s { _ctTableName = a })
+
+newtype CreateTableResponse = CreateTableResponse
+    { _ctrTableDescription :: Maybe TableDescription
+    } deriving (Eq, Show)
+
+-- | 'CreateTableResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'ctrTableDescription' @::@ 'Maybe' 'TableDescription'
+--
+createTableResponse :: CreateTableResponse
+createTableResponse = CreateTableResponse
+    { _ctrTableDescription = Nothing
+    }
+
+ctrTableDescription :: Lens' CreateTableResponse (Maybe TableDescription)
+ctrTableDescription =
+    lens _ctrTableDescription (\s a -> s { _ctrTableDescription = a })
+
+instance ToPath CreateTable where
+    toPath = const "/"
+
+instance ToQuery CreateTable where
+    toQuery = const mempty
+
+instance ToHeaders CreateTable
+
+instance ToJSON CreateTable where
+    toJSON CreateTable{..} = object
+        [ "AttributeDefinitions"   .= _ctAttributeDefinitions
+        , "TableName"              .= _ctTableName
+        , "KeySchema"              .= _ctKeySchema
+        , "LocalSecondaryIndexes"  .= _ctLocalSecondaryIndexes
+        , "GlobalSecondaryIndexes" .= _ctGlobalSecondaryIndexes
+        , "ProvisionedThroughput"  .= _ctProvisionedThroughput
+        ]
+
+instance AWSRequest CreateTable where
+    type Sv CreateTable = DynamoDB
+    type Rs CreateTable = CreateTableResponse
+
+    request  = post "CreateTable"
+    response = jsonResponse
+
+instance FromJSON CreateTableResponse where
+    parseJSON = withObject "CreateTableResponse" $ \o -> CreateTableResponse
+        <$> o .:? "TableDescription"
diff --git a/gen/Network/AWS/DynamoDB/DeleteItem.hs b/gen/Network/AWS/DynamoDB/DeleteItem.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/DeleteItem.hs
@@ -0,0 +1,419 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.DeleteItem
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Deletes a single item in a table by primary key. You can perform a
+-- conditional delete operation that deletes the item if it exists, or if it
+-- has an expected attribute value. In addition to deleting an item, you can
+-- also return the item's attribute values in the same operation, using the
+-- ReturnValues parameter. Unless you specify conditions, the DeleteItem is an
+-- idempotent operation; running it multiple times on the same item or
+-- attribute does not result in an error response. Conditional deletes are
+-- useful for deleting items only if specific conditions are met. If those
+-- conditions are met, DynamoDB performs the delete. Otherwise, the item is
+-- not deleted.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html>
+module Network.AWS.DynamoDB.DeleteItem
+    (
+    -- * Request
+      DeleteItem
+    -- ** Request constructor
+    , deleteItem
+    -- ** Request lenses
+    , diConditionExpression
+    , diConditionalOperator
+    , diExpected
+    , diExpressionAttributeNames
+    , diExpressionAttributeValues
+    , diKey
+    , diReturnConsumedCapacity
+    , diReturnItemCollectionMetrics
+    , diReturnValues
+    , diTableName
+
+    -- * Response
+    , DeleteItemResponse
+    -- ** Response constructor
+    , deleteItemResponse
+    -- ** Response lenses
+    , dirAttributes
+    , dirConsumedCapacity
+    , dirItemCollectionMetrics
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+data DeleteItem = DeleteItem
+    { _diConditionExpression         :: Maybe Text
+    , _diConditionalOperator         :: Maybe Text
+    , _diExpected                    :: Map Text ExpectedAttributeValue
+    , _diExpressionAttributeNames    :: Map Text Text
+    , _diExpressionAttributeValues   :: Map Text AttributeValue
+    , _diKey                         :: Map Text AttributeValue
+    , _diReturnConsumedCapacity      :: Maybe Text
+    , _diReturnItemCollectionMetrics :: Maybe Text
+    , _diReturnValues                :: Maybe Text
+    , _diTableName                   :: Text
+    } deriving (Eq, Show)
+
+-- | 'DeleteItem' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'diConditionExpression' @::@ 'Maybe' 'Text'
+--
+-- * 'diConditionalOperator' @::@ 'Maybe' 'Text'
+--
+-- * 'diExpected' @::@ 'HashMap' 'Text' 'ExpectedAttributeValue'
+--
+-- * 'diExpressionAttributeNames' @::@ 'HashMap' 'Text' 'Text'
+--
+-- * 'diExpressionAttributeValues' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'diKey' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'diReturnConsumedCapacity' @::@ 'Maybe' 'Text'
+--
+-- * 'diReturnItemCollectionMetrics' @::@ 'Maybe' 'Text'
+--
+-- * 'diReturnValues' @::@ 'Maybe' 'Text'
+--
+-- * 'diTableName' @::@ 'Text'
+--
+deleteItem :: Text -- ^ 'diTableName'
+           -> DeleteItem
+deleteItem p1 = DeleteItem
+    { _diTableName                   = p1
+    , _diKey                         = mempty
+    , _diExpected                    = mempty
+    , _diConditionalOperator         = Nothing
+    , _diReturnValues                = Nothing
+    , _diReturnConsumedCapacity      = Nothing
+    , _diReturnItemCollectionMetrics = Nothing
+    , _diConditionExpression         = Nothing
+    , _diExpressionAttributeNames    = mempty
+    , _diExpressionAttributeValues   = mempty
+    }
+
+-- | A condition that must be satisfied in order for a conditional DeleteItem
+-- to succeed. An expression can contain any of the following: Boolean
+-- functions: ATTRIBUTE_EXIST | CONTAINS | BEGINS_WITH Comparison operators:
+-- = | &#x3C;&#x3E; | &#x3C; | &#x3E; | &#x3C;= | &#x3E;= | BETWEEN | IN
+-- Logical operators: NOT | AND | OR.
+diConditionExpression :: Lens' DeleteItem (Maybe Text)
+diConditionExpression =
+    lens _diConditionExpression (\s a -> s { _diConditionExpression = a })
+
+-- | There is a newer parameter available. Use ConditionExpression instead.
+-- Note that if you use ConditionalOperator and ConditionExpression at the
+-- same time, DynamoDB will return a ValidationException exception. This
+-- parameter does not support lists or maps. A logical operator to apply to
+-- the conditions in the Expected map: AND - If all of the conditions
+-- evaluate to true, then the entire map evaluates to true. OR - If at least
+-- one of the conditions evaluate to true, then the entire map evaluates to
+-- true. If you omit ConditionalOperator, then AND is the default. The
+-- operation will succeed only if the entire map evaluates to true.
+diConditionalOperator :: Lens' DeleteItem (Maybe Text)
+diConditionalOperator =
+    lens _diConditionalOperator (\s a -> s { _diConditionalOperator = a })
+
+-- | There is a newer parameter available. Use ConditionExpression instead.
+-- Note that if you use Expected and ConditionExpression at the same time,
+-- DynamoDB will return a ValidationException exception. This parameter does
+-- not support lists or maps. A map of attribute/condition pairs. Expected
+-- provides a conditional block for the DeleteItem operation. Each element
+-- of Expected consists of an attribute name, a comparison operator, and one
+-- or more values. DynamoDB compares the attribute with the value(s) you
+-- supplied, using the comparison operator. For each Expected element, the
+-- result of the evaluation is either true or false. If you specify more
+-- than one element in the Expected map, then by default all of the
+-- conditions must evaluate to true. In other words, the conditions are
+-- ANDed together. (You can use the ConditionalOperator parameter to OR the
+-- conditions instead. If you do this, then at least one of the conditions
+-- must evaluate to true, rather than all of them.) If the Expected map
+-- evaluates to true, then the conditional operation succeeds; otherwise, it
+-- fails. Expected contains the following: AttributeValueList - One or more
+-- values to evaluate against the supplied attribute. The number of values
+-- in the list depends on the ComparisonOperator being used. For type
+-- Number, value comparisons are numeric. String value comparisons for
+-- greater than, equals, or less than are based on ASCII character code
+-- values. For example, a is greater than A, and aa is greater than B. For a
+-- list of code values, see
+-- http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters. For type
+-- Binary, DynamoDB treats each byte of the binary data as unsigned when it
+-- compares binary values, for example when evaluating query expressions.
+-- ComparisonOperator - A comparator for evaluating attributes in the
+-- AttributeValueList. When performing the comparison, DynamoDB uses
+-- strongly consistent reads. The following comparison operators are
+-- available: EQ | NE | LE | LT | GE | GT | NOT_NULL | NULL | CONTAINS |
+-- NOT_CONTAINS | BEGINS_WITH | IN | BETWEEN The following are descriptions
+-- of each comparison operator. EQ : Equal. EQ is supported for all
+-- datatypes, including lists and maps. AttributeValueList can contain only
+-- one AttributeValue element of type String, Number, Binary, String Set,
+-- Number Set, or Binary Set. If an item contains an AttributeValue element
+-- of a different type than the one specified in the request, the value does
+-- not match. For example, {"S":"6"} does not equal {"N":"6"}. Also,
+-- {"N":"6"} does not equal {"NS":["6", "2", "1"]}. NE : Not equal. NE is
+-- supported for all datatypes, including lists and maps. AttributeValueList
+-- can contain only one AttributeValue of type String, Number, Binary,
+-- String Set, Number Set, or Binary Set. If an item contains an
+-- AttributeValue of a different type than the one specified in the request,
+-- the value does not match. For example, {"S":"6"} does not equal
+-- {"N":"6"}. Also, {"N":"6"} does not equal {"NS":["6", "2", "1"]}. LE :
+-- Less than or equal. AttributeValueList can contain only one
+-- AttributeValue element of type String, Number, or Binary (not a set
+-- type). If an item contains an AttributeValue element of a different type
+-- than the one specified in the request, the value does not match. For
+-- example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not
+-- compare to {"NS":["6", "2", "1"]}. LT : Less than. AttributeValueList can
+-- contain only one AttributeValue of type String, Number, or Binary (not a
+-- set type). If an item contains an AttributeValue element of a different
+-- type than the one specified in the request, the value does not match. For
+-- example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not
+-- compare to {"NS":["6", "2", "1"]}. GE : Greater than or equal.
+-- AttributeValueList can contain only one AttributeValue element of type
+-- String, Number, or Binary (not a set type). If an item contains an
+-- AttributeValue element of a different type than the one specified in the
+-- request, the value does not match. For example, {"S":"6"} does not equal
+-- {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", "1"]}. GT
+-- : Greater than. AttributeValueList can contain only one AttributeValue
+-- element of type String, Number, or Binary (not a set type). If an item
+-- contains an AttributeValue element of a different type than the one
+-- specified in the request, the value does not match. For example,
+-- {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not compare to
+-- {"NS":["6", "2", "1"]}. NOT_NULL : The attribute exists. NOT_NULL is
+-- supported for all datatypes, including lists and maps. NULL : The
+-- attribute does not exist. NULL is supported for all datatypes, including
+-- lists and maps. CONTAINS : Checks for a subsequence, or value in a set.
+-- AttributeValueList can contain only one AttributeValue element of type
+-- String, Number, or Binary (not a set type). If the target attribute of
+-- the comparison is of type String, then the operator checks for a
+-- substring match. If the target attribute of the comparison is of type
+-- Binary, then the operator looks for a subsequence of the target that
+-- matches the input. If the target attribute of the comparison is a set
+-- ("SS", "NS", or "BS"), then the operator evaluates to true if it finds an
+-- exact match with any member of the set. CONTAINS is supported for lists:
+-- When evaluating "a CONTAINS b", "a" can be a list; however, "b" cannot be
+-- a set, a map, or a list. NOT_CONTAINS : Checks for absence of a
+-- subsequence, or absence of a value in a set. AttributeValueList can
+-- contain only one AttributeValue element of type String, Number, or Binary
+-- (not a set type). If the target attribute of the comparison is a String,
+-- then the operator checks for the absence of a substring match. If the
+-- target attribute of the comparison is Binary, then the operator checks
+-- for the absence of a subsequence of the target that matches the input. If
+-- the target attribute of the comparison is a set ("SS", "NS", or "BS"),
+-- then the operator evaluates to true if it does not find an exact match
+-- with any member of the set. NOT_CONTAINS is supported for lists: When
+-- evaluating "a NOT CONTAINS b", "a" can be a list; however, "b" cannot be
+-- a set, a map, or a list. BEGINS_WITH : Checks for a prefix.
+-- AttributeValueList can contain only one AttributeValue of type String or
+-- Binary (not a Number or a set type). The target attribute of the
+-- comparison must be of type String or Binary (not a Number or a set type).
+-- IN : Checks for matching elements within two sets. AttributeValueList can
+-- contain one or more AttributeValue elements of type String, Number, or
+-- Binary (not a set type). These attributes are compared against an
+-- existing set type attribute of an item. If any elements of the input set
+-- are present in the item attribute, the expression evaluates to true.
+-- BETWEEN : Greater than or equal to the first value, and less than or
+-- equal to the second value. AttributeValueList must contain two
+-- AttributeValue elements of the same type, either String, Number, or
+-- Binary (not a set type). A target attribute matches if the target value
+-- is greater than, or equal to, the first element and less than, or equal
+-- to, the second element. If an item contains an AttributeValue element of
+-- a different type than the one specified in the request, the value does
+-- not match. For example, {"S":"6"} does not compare to {"N":"6"}. Also,
+-- {"N":"6"} does not compare to {"NS":["6", "2", "1"]} For usage examples
+-- of AttributeValueList and ComparisonOperator, see Legacy Conditional
+-- Parameters in the Amazon DynamoDB Developer Guide. For backward
+-- compatibility with previous DynamoDB releases, the following parameters
+-- can be used instead of AttributeValueList and ComparisonOperator: Value -
+-- A value for DynamoDB to compare with an attribute. Exists - A Boolean
+-- value that causes DynamoDB to evaluate the value before attempting the
+-- conditional operation: If Exists is true, DynamoDB will check to see if
+-- that attribute value already exists in the table. If it is found, then
+-- the condition evaluates to true; otherwise the condition evaluate to
+-- false. If Exists is false, DynamoDB assumes that the attribute value does
+-- not exist in the table. If in fact the value does not exist, then the
+-- assumption is valid and the condition evaluates to true. If the value is
+-- found, despite the assumption that it does not exist, the condition
+-- evaluates to false. The Value and Exists parameters are incompatible with
+-- AttributeValueList and ComparisonOperator. Note that if you use both sets
+-- of parameters at once, DynamoDB will return a ValidationException
+-- exception.
+diExpected :: Lens' DeleteItem (HashMap Text ExpectedAttributeValue)
+diExpected = lens _diExpected (\s a -> s { _diExpected = a }) . _Map
+
+-- | One or more substitution tokens for simplifying complex expressions. The
+-- following are some use cases for an ExpressionAttributeNames value: To
+-- shorten an attribute name that is very long or unwieldy in an expression.
+-- To create a placeholder for repeating occurrences of an attribute name in
+-- an expression. To prevent special characters in an attribute name from
+-- being misinterpreted in an expression. Use the # character in an
+-- expression to dereference an attribute name. For example, consider the
+-- following expression: order.customerInfo.LastName = "Smith" OR
+-- order.customerInfo.LastName = "Jones" Now suppose that you specified the
+-- following for ExpressionAttributeNames:
+-- {"n":"order.customerInfo.LastName"} The expression can now be simplified
+-- as follows: #n = "Smith" OR #n = "Jones".
+diExpressionAttributeNames :: Lens' DeleteItem (HashMap Text Text)
+diExpressionAttributeNames =
+    lens _diExpressionAttributeNames
+        (\s a -> s { _diExpressionAttributeNames = a })
+            . _Map
+
+-- | One or more values that can be substituted in an expression. Use the :
+-- character in an expression to dereference an attribute value. For
+-- example, consider the following expression: ProductStatus IN
+-- ("Available","Backordered","Discontinued") Now suppose that you specified
+-- the following for ExpressionAttributeValues: { "a":{"S":"Available"},
+-- "b":{"S":"Backordered"}, "d":{"S":"Discontinued"} } The expression can
+-- now be simplified as follows: ProductStatus IN (:a,:b,:c).
+diExpressionAttributeValues :: Lens' DeleteItem (HashMap Text AttributeValue)
+diExpressionAttributeValues =
+    lens _diExpressionAttributeValues
+        (\s a -> s { _diExpressionAttributeValues = a })
+            . _Map
+
+-- | A map of attribute names to AttributeValue objects, representing the
+-- primary key of the item to delete. For the primary key, you must provide
+-- all of the attributes. For example, with a hash type primary key, you
+-- only need to specify the hash attribute. For a hash-and-range type
+-- primary key, you must specify both the hash attribute and the range
+-- attribute.
+diKey :: Lens' DeleteItem (HashMap Text AttributeValue)
+diKey = lens _diKey (\s a -> s { _diKey = a }) . _Map
+
+diReturnConsumedCapacity :: Lens' DeleteItem (Maybe Text)
+diReturnConsumedCapacity =
+    lens _diReturnConsumedCapacity
+        (\s a -> s { _diReturnConsumedCapacity = a })
+
+-- | A value that if set to SIZE, the response includes statistics about item
+-- collections, if any, that were modified during the operation are returned
+-- in the response. If set to NONE (the default), no statistics are
+-- returned.
+diReturnItemCollectionMetrics :: Lens' DeleteItem (Maybe Text)
+diReturnItemCollectionMetrics =
+    lens _diReturnItemCollectionMetrics
+        (\s a -> s { _diReturnItemCollectionMetrics = a })
+
+-- | Use ReturnValues if you want to get the item attributes as they appeared
+-- before they were deleted. For DeleteItem, the valid values are: NONE - If
+-- ReturnValues is not specified, or if its value is NONE, then nothing is
+-- returned. (This setting is the default for ReturnValues.) ALL_OLD - The
+-- content of the old item is returned.
+diReturnValues :: Lens' DeleteItem (Maybe Text)
+diReturnValues = lens _diReturnValues (\s a -> s { _diReturnValues = a })
+
+-- | The name of the table from which to delete the item.
+diTableName :: Lens' DeleteItem Text
+diTableName = lens _diTableName (\s a -> s { _diTableName = a })
+
+data DeleteItemResponse = DeleteItemResponse
+    { _dirAttributes            :: Map Text AttributeValue
+    , _dirConsumedCapacity      :: Maybe ConsumedCapacity
+    , _dirItemCollectionMetrics :: Maybe ItemCollectionMetrics
+    } deriving (Eq, Show)
+
+-- | 'DeleteItemResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dirAttributes' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'dirConsumedCapacity' @::@ 'Maybe' 'ConsumedCapacity'
+--
+-- * 'dirItemCollectionMetrics' @::@ 'Maybe' 'ItemCollectionMetrics'
+--
+deleteItemResponse :: DeleteItemResponse
+deleteItemResponse = DeleteItemResponse
+    { _dirAttributes            = mempty
+    , _dirConsumedCapacity      = Nothing
+    , _dirItemCollectionMetrics = Nothing
+    }
+
+-- | A map of attribute names to AttributeValue objects, representing the item
+-- as it appeared before the DeleteItem operation. This map appears in the
+-- response only if ReturnValues was specified as ALL_OLD in the request.
+dirAttributes :: Lens' DeleteItemResponse (HashMap Text AttributeValue)
+dirAttributes = lens _dirAttributes (\s a -> s { _dirAttributes = a }) . _Map
+
+dirConsumedCapacity :: Lens' DeleteItemResponse (Maybe ConsumedCapacity)
+dirConsumedCapacity =
+    lens _dirConsumedCapacity (\s a -> s { _dirConsumedCapacity = a })
+
+-- | Information about item collections, if any, that were affected by the
+-- operation. ItemCollectionMetrics is only returned if the request asked
+-- for it. If the table does not have any local secondary indexes, this
+-- information is not returned in the response. Each ItemCollectionMetrics
+-- element consists of: ItemCollectionKey - The hash key value of the item
+-- collection. This is the same as the hash key of the item.
+-- SizeEstimateRange - An estimate of item collection size, in gigabytes.
+-- This value is a two-element array containing a lower bound and an upper
+-- bound for the estimate. The estimate includes the size of all the items
+-- in the table, plus the size of all attributes projected into all of the
+-- local secondary indexes on that table. Use this estimate to measure
+-- whether a local secondary index is approaching its size limit. The
+-- estimate is subject to change over time; therefore, do not rely on the
+-- precision or accuracy of the estimate.
+dirItemCollectionMetrics :: Lens' DeleteItemResponse (Maybe ItemCollectionMetrics)
+dirItemCollectionMetrics =
+    lens _dirItemCollectionMetrics
+        (\s a -> s { _dirItemCollectionMetrics = a })
+
+instance ToPath DeleteItem where
+    toPath = const "/"
+
+instance ToQuery DeleteItem where
+    toQuery = const mempty
+
+instance ToHeaders DeleteItem
+
+instance ToJSON DeleteItem where
+    toJSON DeleteItem{..} = object
+        [ "TableName"                   .= _diTableName
+        , "Key"                         .= _diKey
+        , "Expected"                    .= _diExpected
+        , "ConditionalOperator"         .= _diConditionalOperator
+        , "ReturnValues"                .= _diReturnValues
+        , "ReturnConsumedCapacity"      .= _diReturnConsumedCapacity
+        , "ReturnItemCollectionMetrics" .= _diReturnItemCollectionMetrics
+        , "ConditionExpression"         .= _diConditionExpression
+        , "ExpressionAttributeNames"    .= _diExpressionAttributeNames
+        , "ExpressionAttributeValues"   .= _diExpressionAttributeValues
+        ]
+
+instance AWSRequest DeleteItem where
+    type Sv DeleteItem = DynamoDB
+    type Rs DeleteItem = DeleteItemResponse
+
+    request  = post "DeleteItem"
+    response = jsonResponse
+
+instance FromJSON DeleteItemResponse where
+    parseJSON = withObject "DeleteItemResponse" $ \o -> DeleteItemResponse
+        <$> o .:  "Attributes"
+        <*> o .:? "ConsumedCapacity"
+        <*> o .:? "ItemCollectionMetrics"
diff --git a/gen/Network/AWS/DynamoDB/DeleteTable.hs b/gen/Network/AWS/DynamoDB/DeleteTable.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/DeleteTable.hs
@@ -0,0 +1,117 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.DeleteTable
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | The DeleteTable operation deletes a table and all of its items. After a
+-- DeleteTable request, the specified table is in the DELETING state until
+-- DynamoDB completes the deletion. If the table is in the ACTIVE state, you
+-- can delete it. If a table is in CREATING or UPDATING states, then DynamoDB
+-- returns a ResourceInUseException. If the specified table does not exist,
+-- DynamoDB returns a ResourceNotFoundException. If table is already in the
+-- DELETING state, no error is returned. When you delete a table, any indexes
+-- on that table are also deleted. Use the DescribeTable API to check the
+-- status of the table.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteTable.html>
+module Network.AWS.DynamoDB.DeleteTable
+    (
+    -- * Request
+      DeleteTable
+    -- ** Request constructor
+    , deleteTable
+    -- ** Request lenses
+    , dtTableName
+
+    -- * Response
+    , DeleteTableResponse
+    -- ** Response constructor
+    , deleteTableResponse
+    -- ** Response lenses
+    , dtrTableDescription
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+newtype DeleteTable = DeleteTable
+    { _dtTableName :: Text
+    } deriving (Eq, Ord, Show, Monoid, IsString)
+
+-- | 'DeleteTable' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dtTableName' @::@ 'Text'
+--
+deleteTable :: Text -- ^ 'dtTableName'
+            -> DeleteTable
+deleteTable p1 = DeleteTable
+    { _dtTableName = p1
+    }
+
+-- | The name of the table to delete.
+dtTableName :: Lens' DeleteTable Text
+dtTableName = lens _dtTableName (\s a -> s { _dtTableName = a })
+
+newtype DeleteTableResponse = DeleteTableResponse
+    { _dtrTableDescription :: Maybe TableDescription
+    } deriving (Eq, Show)
+
+-- | 'DeleteTableResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dtrTableDescription' @::@ 'Maybe' 'TableDescription'
+--
+deleteTableResponse :: DeleteTableResponse
+deleteTableResponse = DeleteTableResponse
+    { _dtrTableDescription = Nothing
+    }
+
+dtrTableDescription :: Lens' DeleteTableResponse (Maybe TableDescription)
+dtrTableDescription =
+    lens _dtrTableDescription (\s a -> s { _dtrTableDescription = a })
+
+instance ToPath DeleteTable where
+    toPath = const "/"
+
+instance ToQuery DeleteTable where
+    toQuery = const mempty
+
+instance ToHeaders DeleteTable
+
+instance ToJSON DeleteTable where
+    toJSON DeleteTable{..} = object
+        [ "TableName" .= _dtTableName
+        ]
+
+instance AWSRequest DeleteTable where
+    type Sv DeleteTable = DynamoDB
+    type Rs DeleteTable = DeleteTableResponse
+
+    request  = post "DeleteTable"
+    response = jsonResponse
+
+instance FromJSON DeleteTableResponse where
+    parseJSON = withObject "DeleteTableResponse" $ \o -> DeleteTableResponse
+        <$> o .:? "TableDescription"
diff --git a/gen/Network/AWS/DynamoDB/DescribeTable.hs b/gen/Network/AWS/DynamoDB/DescribeTable.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/DescribeTable.hs
@@ -0,0 +1,110 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.DescribeTable
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Returns information about the table, including the current status of the
+-- table, when it was created, the primary key schema, and any indexes on the
+-- table.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html>
+module Network.AWS.DynamoDB.DescribeTable
+    (
+    -- * Request
+      DescribeTable
+    -- ** Request constructor
+    , describeTable
+    -- ** Request lenses
+    , dt1TableName
+
+    -- * Response
+    , DescribeTableResponse
+    -- ** Response constructor
+    , describeTableResponse
+    -- ** Response lenses
+    , dtrTable
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+newtype DescribeTable = DescribeTable
+    { _dt1TableName :: Text
+    } deriving (Eq, Ord, Show, Monoid, IsString)
+
+-- | 'DescribeTable' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dt1TableName' @::@ 'Text'
+--
+describeTable :: Text -- ^ 'dt1TableName'
+              -> DescribeTable
+describeTable p1 = DescribeTable
+    { _dt1TableName = p1
+    }
+
+-- | The name of the table to describe.
+dt1TableName :: Lens' DescribeTable Text
+dt1TableName = lens _dt1TableName (\s a -> s { _dt1TableName = a })
+
+newtype DescribeTableResponse = DescribeTableResponse
+    { _dtrTable :: Maybe TableDescription
+    } deriving (Eq, Show)
+
+-- | 'DescribeTableResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dtrTable' @::@ 'Maybe' 'TableDescription'
+--
+describeTableResponse :: DescribeTableResponse
+describeTableResponse = DescribeTableResponse
+    { _dtrTable = Nothing
+    }
+
+dtrTable :: Lens' DescribeTableResponse (Maybe TableDescription)
+dtrTable = lens _dtrTable (\s a -> s { _dtrTable = a })
+
+instance ToPath DescribeTable where
+    toPath = const "/"
+
+instance ToQuery DescribeTable where
+    toQuery = const mempty
+
+instance ToHeaders DescribeTable
+
+instance ToJSON DescribeTable where
+    toJSON DescribeTable{..} = object
+        [ "TableName" .= _dt1TableName
+        ]
+
+instance AWSRequest DescribeTable where
+    type Sv DescribeTable = DynamoDB
+    type Rs DescribeTable = DescribeTableResponse
+
+    request  = post "DescribeTable"
+    response = jsonResponse
+
+instance FromJSON DescribeTableResponse where
+    parseJSON = withObject "DescribeTableResponse" $ \o -> DescribeTableResponse
+        <$> o .:? "Table"
diff --git a/gen/Network/AWS/DynamoDB/GetItem.hs b/gen/Network/AWS/DynamoDB/GetItem.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/GetItem.hs
@@ -0,0 +1,224 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.GetItem
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | The GetItem operation returns a set of attributes for the item with the
+-- given primary key. If there is no matching item, GetItem does not return
+-- any data. GetItem provides an eventually consistent read by default. If
+-- your application requires a strongly consistent read, set ConsistentRead to
+-- true. Although a strongly consistent read might take more time than an
+-- eventually consistent read, it always returns the last updated value.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html>
+module Network.AWS.DynamoDB.GetItem
+    (
+    -- * Request
+      GetItem
+    -- ** Request constructor
+    , getItem
+    -- ** Request lenses
+    , giAttributesToGet
+    , giConsistentRead
+    , giExpressionAttributeNames
+    , giKey
+    , giProjectionExpression
+    , giReturnConsumedCapacity
+    , giTableName
+
+    -- * Response
+    , GetItemResponse
+    -- ** Response constructor
+    , getItemResponse
+    -- ** Response lenses
+    , girConsumedCapacity
+    , girItem
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+data GetItem = GetItem
+    { _giAttributesToGet          :: List1 "AttributesToGet" Text
+    , _giConsistentRead           :: Maybe Bool
+    , _giExpressionAttributeNames :: Map Text Text
+    , _giKey                      :: Map Text AttributeValue
+    , _giProjectionExpression     :: Maybe Text
+    , _giReturnConsumedCapacity   :: Maybe Text
+    , _giTableName                :: Text
+    } deriving (Eq, Show)
+
+-- | 'GetItem' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'giAttributesToGet' @::@ 'NonEmpty' 'Text'
+--
+-- * 'giConsistentRead' @::@ 'Maybe' 'Bool'
+--
+-- * 'giExpressionAttributeNames' @::@ 'HashMap' 'Text' 'Text'
+--
+-- * 'giKey' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'giProjectionExpression' @::@ 'Maybe' 'Text'
+--
+-- * 'giReturnConsumedCapacity' @::@ 'Maybe' 'Text'
+--
+-- * 'giTableName' @::@ 'Text'
+--
+getItem :: Text -- ^ 'giTableName'
+        -> NonEmpty Text -- ^ 'giAttributesToGet'
+        -> GetItem
+getItem p1 p2 = GetItem
+    { _giTableName                = p1
+    , _giAttributesToGet          = withIso _List1 (const id) p2
+    , _giKey                      = mempty
+    , _giConsistentRead           = Nothing
+    , _giReturnConsumedCapacity   = Nothing
+    , _giProjectionExpression     = Nothing
+    , _giExpressionAttributeNames = mempty
+    }
+
+-- | There is a newer parameter available. Use ProjectionExpression instead.
+-- Note that if you use AttributesToGet and ProjectionExpression at the same
+-- time, DynamoDB will return a ValidationException exception. This
+-- parameter allows you to retrieve lists or maps; however, it cannot
+-- retrieve individual list or map elements. The names of one or more
+-- attributes to retrieve. If no attribute names are specified, then all
+-- attributes will be returned. If any of the requested attributes are not
+-- found, they will not appear in the result. Note that AttributesToGet has
+-- no effect on provisioned throughput consumption. DynamoDB determines
+-- capacity units consumed based on item size, not on the amount of data
+-- that is returned to an application.
+giAttributesToGet :: Lens' GetItem (NonEmpty Text)
+giAttributesToGet =
+    lens _giAttributesToGet (\s a -> s { _giAttributesToGet = a })
+        . _List1
+
+-- | A value that if set to true, then the operation uses strongly consistent
+-- reads; otherwise, eventually consistent reads are used.
+giConsistentRead :: Lens' GetItem (Maybe Bool)
+giConsistentRead = lens _giConsistentRead (\s a -> s { _giConsistentRead = a })
+
+-- | One or more substitution tokens for simplifying complex expressions. The
+-- following are some use cases for an ExpressionAttributeNames value: To
+-- shorten an attribute name that is very long or unwieldy in an expression.
+-- To create a placeholder for repeating occurrences of an attribute name in
+-- an expression. To prevent special characters in an attribute name from
+-- being misinterpreted in an expression. Use the # character in an
+-- expression to dereference an attribute name. For example, consider the
+-- following expression: order.customerInfo.LastName = "Smith" OR
+-- order.customerInfo.LastName = "Jones" Now suppose that you specified the
+-- following for ExpressionAttributeNames:
+-- {"n":"order.customerInfo.LastName"} The expression can now be simplified
+-- as follows: #n = "Smith" OR #n = "Jones".
+giExpressionAttributeNames :: Lens' GetItem (HashMap Text Text)
+giExpressionAttributeNames =
+    lens _giExpressionAttributeNames
+        (\s a -> s { _giExpressionAttributeNames = a })
+            . _Map
+
+-- | A map of attribute names to AttributeValue objects, representing the
+-- primary key of the item to retrieve. For the primary key, you must
+-- provide all of the attributes. For example, with a hash type primary key,
+-- you only need to specify the hash attribute. For a hash-and-range type
+-- primary key, you must specify both the hash attribute and the range
+-- attribute.
+giKey :: Lens' GetItem (HashMap Text AttributeValue)
+giKey = lens _giKey (\s a -> s { _giKey = a }) . _Map
+
+-- | One or more attributes to retrieve from the table. These attributes can
+-- include scalars, sets, or elements of a JSON document. The attributes in
+-- the expression must be separated by commas. If no attribute names are
+-- specified, then all attributes will be returned. If any of the requested
+-- attributes are not found, they will not appear in the result.
+giProjectionExpression :: Lens' GetItem (Maybe Text)
+giProjectionExpression =
+    lens _giProjectionExpression (\s a -> s { _giProjectionExpression = a })
+
+giReturnConsumedCapacity :: Lens' GetItem (Maybe Text)
+giReturnConsumedCapacity =
+    lens _giReturnConsumedCapacity
+        (\s a -> s { _giReturnConsumedCapacity = a })
+
+-- | The name of the table containing the requested item.
+giTableName :: Lens' GetItem Text
+giTableName = lens _giTableName (\s a -> s { _giTableName = a })
+
+data GetItemResponse = GetItemResponse
+    { _girConsumedCapacity :: Maybe ConsumedCapacity
+    , _girItem             :: Map Text AttributeValue
+    } deriving (Eq, Show)
+
+-- | 'GetItemResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'girConsumedCapacity' @::@ 'Maybe' 'ConsumedCapacity'
+--
+-- * 'girItem' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+getItemResponse :: GetItemResponse
+getItemResponse = GetItemResponse
+    { _girItem             = mempty
+    , _girConsumedCapacity = Nothing
+    }
+
+girConsumedCapacity :: Lens' GetItemResponse (Maybe ConsumedCapacity)
+girConsumedCapacity =
+    lens _girConsumedCapacity (\s a -> s { _girConsumedCapacity = a })
+
+-- | A map of attribute names to AttributeValue objects, as specified by
+-- AttributesToGet.
+girItem :: Lens' GetItemResponse (HashMap Text AttributeValue)
+girItem = lens _girItem (\s a -> s { _girItem = a }) . _Map
+
+instance ToPath GetItem where
+    toPath = const "/"
+
+instance ToQuery GetItem where
+    toQuery = const mempty
+
+instance ToHeaders GetItem
+
+instance ToJSON GetItem where
+    toJSON GetItem{..} = object
+        [ "TableName"                .= _giTableName
+        , "Key"                      .= _giKey
+        , "AttributesToGet"          .= _giAttributesToGet
+        , "ConsistentRead"           .= _giConsistentRead
+        , "ReturnConsumedCapacity"   .= _giReturnConsumedCapacity
+        , "ProjectionExpression"     .= _giProjectionExpression
+        , "ExpressionAttributeNames" .= _giExpressionAttributeNames
+        ]
+
+instance AWSRequest GetItem where
+    type Sv GetItem = DynamoDB
+    type Rs GetItem = GetItemResponse
+
+    request  = post "GetItem"
+    response = jsonResponse
+
+instance FromJSON GetItemResponse where
+    parseJSON = withObject "GetItemResponse" $ \o -> GetItemResponse
+        <$> o .:? "ConsumedCapacity"
+        <*> o .:  "Item"
diff --git a/gen/Network/AWS/DynamoDB/ListTables.hs b/gen/Network/AWS/DynamoDB/ListTables.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/ListTables.hs
@@ -0,0 +1,151 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.ListTables
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Returns an array of table names associated with the current account and
+-- endpoint. The output from ListTables is paginated, with each page returning
+-- a maximum of 100 table names.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_ListTables.html>
+module Network.AWS.DynamoDB.ListTables
+    (
+    -- * Request
+      ListTables
+    -- ** Request constructor
+    , listTables
+    -- ** Request lenses
+    , ltExclusiveStartTableName
+    , ltLimit
+
+    -- * Response
+    , ListTablesResponse
+    -- ** Response constructor
+    , listTablesResponse
+    -- ** Response lenses
+    , ltrLastEvaluatedTableName
+    , ltrTableNames
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+data ListTables = ListTables
+    { _ltExclusiveStartTableName :: Maybe Text
+    , _ltLimit                   :: Maybe Nat
+    } deriving (Eq, Ord, Show)
+
+-- | 'ListTables' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'ltExclusiveStartTableName' @::@ 'Maybe' 'Text'
+--
+-- * 'ltLimit' @::@ 'Maybe' 'Natural'
+--
+listTables :: ListTables
+listTables = ListTables
+    { _ltExclusiveStartTableName = Nothing
+    , _ltLimit                   = Nothing
+    }
+
+-- | The first table name that this operation will evaluate. Use the value
+-- that was returned for LastEvaluatedTableName in a previous operation, so
+-- that you can obtain the next page of results.
+ltExclusiveStartTableName :: Lens' ListTables (Maybe Text)
+ltExclusiveStartTableName =
+    lens _ltExclusiveStartTableName
+        (\s a -> s { _ltExclusiveStartTableName = a })
+
+-- | A maximum number of table names to return. If this parameter is not
+-- specified, the limit is 100.
+ltLimit :: Lens' ListTables (Maybe Natural)
+ltLimit = lens _ltLimit (\s a -> s { _ltLimit = a }) . mapping _Nat
+
+data ListTablesResponse = ListTablesResponse
+    { _ltrLastEvaluatedTableName :: Maybe Text
+    , _ltrTableNames             :: List "TableNames" Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'ListTablesResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'ltrLastEvaluatedTableName' @::@ 'Maybe' 'Text'
+--
+-- * 'ltrTableNames' @::@ ['Text']
+--
+listTablesResponse :: ListTablesResponse
+listTablesResponse = ListTablesResponse
+    { _ltrTableNames             = mempty
+    , _ltrLastEvaluatedTableName = Nothing
+    }
+
+-- | The name of the last table in the current page of results. Use this value
+-- as the ExclusiveStartTableName in a new request to obtain the next page
+-- of results, until all the table names are returned. If you do not receive
+-- a LastEvaluatedTableName value in the response, this means that there are
+-- no more table names to be retrieved.
+ltrLastEvaluatedTableName :: Lens' ListTablesResponse (Maybe Text)
+ltrLastEvaluatedTableName =
+    lens _ltrLastEvaluatedTableName
+        (\s a -> s { _ltrLastEvaluatedTableName = a })
+
+-- | The names of the tables associated with the current account at the
+-- current endpoint. The maximum size of this array is 100. If
+-- LastEvaluatedTableName also appears in the output, you can use this value
+-- as the ExclusiveStartTableName parameter in a subsequent ListTables
+-- request and obtain the next page of results.
+ltrTableNames :: Lens' ListTablesResponse [Text]
+ltrTableNames = lens _ltrTableNames (\s a -> s { _ltrTableNames = a }) . _List
+
+instance ToPath ListTables where
+    toPath = const "/"
+
+instance ToQuery ListTables where
+    toQuery = const mempty
+
+instance ToHeaders ListTables
+
+instance ToJSON ListTables where
+    toJSON ListTables{..} = object
+        [ "ExclusiveStartTableName" .= _ltExclusiveStartTableName
+        , "Limit"                   .= _ltLimit
+        ]
+
+instance AWSRequest ListTables where
+    type Sv ListTables = DynamoDB
+    type Rs ListTables = ListTablesResponse
+
+    request  = post "ListTables"
+    response = jsonResponse
+
+instance FromJSON ListTablesResponse where
+    parseJSON = withObject "ListTablesResponse" $ \o -> ListTablesResponse
+        <$> o .:? "LastEvaluatedTableName"
+        <*> o .:  "TableNames"
+
+instance AWSPager ListTables where
+    page rq rs
+        | stop (rq ^. ltExclusiveStartTableName) = Nothing
+        | otherwise = (\x -> rq & ltExclusiveStartTableName ?~ x)
+            <$> (rs ^. ltrLastEvaluatedTableName)
diff --git a/gen/Network/AWS/DynamoDB/PutItem.hs b/gen/Network/AWS/DynamoDB/PutItem.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/PutItem.hs
@@ -0,0 +1,431 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.PutItem
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Creates a new item, or replaces an old item with a new item. If an item
+-- that has the same primary key as the new item already exists in the
+-- specified table, the new item completely replaces the existing item. You
+-- can perform a conditional put operation (add a new item if one with the
+-- specified primary key doesn't exist), or replace an existing item if it has
+-- certain attribute values. In addition to putting an item, you can also
+-- return the item's attribute values in the same operation, using the
+-- ReturnValues parameter. When you add an item, the primary key attribute(s)
+-- are the only required attributes. Attribute values cannot be null. String
+-- and Binary type attributes must have lengths greater than zero. Set type
+-- attributes cannot be empty. Requests with empty values will be rejected
+-- with a ValidationException exception. You can request that PutItem return
+-- either a copy of the original item (before the update) or a copy of the
+-- updated item (after the update). For more information, see the ReturnValues
+-- description below. For more information about using this API, see Working
+-- with Items in the Amazon DynamoDB Developer Guide.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html>
+module Network.AWS.DynamoDB.PutItem
+    (
+    -- * Request
+      PutItem
+    -- ** Request constructor
+    , putItem
+    -- ** Request lenses
+    , piConditionExpression
+    , piConditionalOperator
+    , piExpected
+    , piExpressionAttributeNames
+    , piExpressionAttributeValues
+    , piItem
+    , piReturnConsumedCapacity
+    , piReturnItemCollectionMetrics
+    , piReturnValues
+    , piTableName
+
+    -- * Response
+    , PutItemResponse
+    -- ** Response constructor
+    , putItemResponse
+    -- ** Response lenses
+    , pirAttributes
+    , pirConsumedCapacity
+    , pirItemCollectionMetrics
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+data PutItem = PutItem
+    { _piConditionExpression         :: Maybe Text
+    , _piConditionalOperator         :: Maybe Text
+    , _piExpected                    :: Map Text ExpectedAttributeValue
+    , _piExpressionAttributeNames    :: Map Text Text
+    , _piExpressionAttributeValues   :: Map Text AttributeValue
+    , _piItem                        :: Map Text AttributeValue
+    , _piReturnConsumedCapacity      :: Maybe Text
+    , _piReturnItemCollectionMetrics :: Maybe Text
+    , _piReturnValues                :: Maybe Text
+    , _piTableName                   :: Text
+    } deriving (Eq, Show)
+
+-- | 'PutItem' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'piConditionExpression' @::@ 'Maybe' 'Text'
+--
+-- * 'piConditionalOperator' @::@ 'Maybe' 'Text'
+--
+-- * 'piExpected' @::@ 'HashMap' 'Text' 'ExpectedAttributeValue'
+--
+-- * 'piExpressionAttributeNames' @::@ 'HashMap' 'Text' 'Text'
+--
+-- * 'piExpressionAttributeValues' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'piItem' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'piReturnConsumedCapacity' @::@ 'Maybe' 'Text'
+--
+-- * 'piReturnItemCollectionMetrics' @::@ 'Maybe' 'Text'
+--
+-- * 'piReturnValues' @::@ 'Maybe' 'Text'
+--
+-- * 'piTableName' @::@ 'Text'
+--
+putItem :: Text -- ^ 'piTableName'
+        -> PutItem
+putItem p1 = PutItem
+    { _piTableName                   = p1
+    , _piItem                        = mempty
+    , _piExpected                    = mempty
+    , _piReturnValues                = Nothing
+    , _piReturnConsumedCapacity      = Nothing
+    , _piReturnItemCollectionMetrics = Nothing
+    , _piConditionalOperator         = Nothing
+    , _piConditionExpression         = Nothing
+    , _piExpressionAttributeNames    = mempty
+    , _piExpressionAttributeValues   = mempty
+    }
+
+-- | A condition that must be satisfied in order for a conditional PutItem
+-- operation to succeed. An expression can contain any of the following:
+-- Boolean functions: ATTRIBUTE_EXIST | CONTAINS | BEGINS_WITH Comparison
+-- operators: = | &#x3C;&#x3E; | &#x3C; | &#x3E; | &#x3C;= | &#x3E;= |
+-- BETWEEN | IN Logical operators: NOT | AND | OR.
+piConditionExpression :: Lens' PutItem (Maybe Text)
+piConditionExpression =
+    lens _piConditionExpression (\s a -> s { _piConditionExpression = a })
+
+-- | There is a newer parameter available. Use ConditionExpression instead.
+-- Note that if you use ConditionalOperator and ConditionExpression at the
+-- same time, DynamoDB will return a ValidationException exception. This
+-- parameter does not support lists or maps. A logical operator to apply to
+-- the conditions in the Expected map: AND - If all of the conditions
+-- evaluate to true, then the entire map evaluates to true. OR - If at least
+-- one of the conditions evaluate to true, then the entire map evaluates to
+-- true. If you omit ConditionalOperator, then AND is the default. The
+-- operation will succeed only if the entire map evaluates to true.
+piConditionalOperator :: Lens' PutItem (Maybe Text)
+piConditionalOperator =
+    lens _piConditionalOperator (\s a -> s { _piConditionalOperator = a })
+
+-- | There is a newer parameter available. Use ConditionExpression instead.
+-- Note that if you use Expected and ConditionExpression at the same time,
+-- DynamoDB will return a ValidationException exception. This parameter does
+-- not support lists or maps. A map of attribute/condition pairs. Expected
+-- provides a conditional block for the PutItem operation. Each element of
+-- Expected consists of an attribute name, a comparison operator, and one or
+-- more values. DynamoDB compares the attribute with the value(s) you
+-- supplied, using the comparison operator. For each Expected element, the
+-- result of the evaluation is either true or false. If you specify more
+-- than one element in the Expected map, then by default all of the
+-- conditions must evaluate to true. In other words, the conditions are
+-- ANDed together. (You can use the ConditionalOperator parameter to OR the
+-- conditions instead. If you do this, then at least one of the conditions
+-- must evaluate to true, rather than all of them.) If the Expected map
+-- evaluates to true, then the conditional operation succeeds; otherwise, it
+-- fails. Expected contains the following: AttributeValueList - One or more
+-- values to evaluate against the supplied attribute. The number of values
+-- in the list depends on the ComparisonOperator being used. For type
+-- Number, value comparisons are numeric. String value comparisons for
+-- greater than, equals, or less than are based on ASCII character code
+-- values. For example, a is greater than A, and aa is greater than B. For a
+-- list of code values, see
+-- http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters. For type
+-- Binary, DynamoDB treats each byte of the binary data as unsigned when it
+-- compares binary values, for example when evaluating query expressions.
+-- ComparisonOperator - A comparator for evaluating attributes in the
+-- AttributeValueList. When performing the comparison, DynamoDB uses
+-- strongly consistent reads. The following comparison operators are
+-- available: EQ | NE | LE | LT | GE | GT | NOT_NULL | NULL | CONTAINS |
+-- NOT_CONTAINS | BEGINS_WITH | IN | BETWEEN The following are descriptions
+-- of each comparison operator. EQ : Equal. EQ is supported for all
+-- datatypes, including lists and maps. AttributeValueList can contain only
+-- one AttributeValue element of type String, Number, Binary, String Set,
+-- Number Set, or Binary Set. If an item contains an AttributeValue element
+-- of a different type than the one specified in the request, the value does
+-- not match. For example, {"S":"6"} does not equal {"N":"6"}. Also,
+-- {"N":"6"} does not equal {"NS":["6", "2", "1"]}. NE : Not equal. NE is
+-- supported for all datatypes, including lists and maps. AttributeValueList
+-- can contain only one AttributeValue of type String, Number, Binary,
+-- String Set, Number Set, or Binary Set. If an item contains an
+-- AttributeValue of a different type than the one specified in the request,
+-- the value does not match. For example, {"S":"6"} does not equal
+-- {"N":"6"}. Also, {"N":"6"} does not equal {"NS":["6", "2", "1"]}. LE :
+-- Less than or equal. AttributeValueList can contain only one
+-- AttributeValue element of type String, Number, or Binary (not a set
+-- type). If an item contains an AttributeValue element of a different type
+-- than the one specified in the request, the value does not match. For
+-- example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not
+-- compare to {"NS":["6", "2", "1"]}. LT : Less than. AttributeValueList can
+-- contain only one AttributeValue of type String, Number, or Binary (not a
+-- set type). If an item contains an AttributeValue element of a different
+-- type than the one specified in the request, the value does not match. For
+-- example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not
+-- compare to {"NS":["6", "2", "1"]}. GE : Greater than or equal.
+-- AttributeValueList can contain only one AttributeValue element of type
+-- String, Number, or Binary (not a set type). If an item contains an
+-- AttributeValue element of a different type than the one specified in the
+-- request, the value does not match. For example, {"S":"6"} does not equal
+-- {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", "1"]}. GT
+-- : Greater than. AttributeValueList can contain only one AttributeValue
+-- element of type String, Number, or Binary (not a set type). If an item
+-- contains an AttributeValue element of a different type than the one
+-- specified in the request, the value does not match. For example,
+-- {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not compare to
+-- {"NS":["6", "2", "1"]}. NOT_NULL : The attribute exists. NOT_NULL is
+-- supported for all datatypes, including lists and maps. NULL : The
+-- attribute does not exist. NULL is supported for all datatypes, including
+-- lists and maps. CONTAINS : Checks for a subsequence, or value in a set.
+-- AttributeValueList can contain only one AttributeValue element of type
+-- String, Number, or Binary (not a set type). If the target attribute of
+-- the comparison is of type String, then the operator checks for a
+-- substring match. If the target attribute of the comparison is of type
+-- Binary, then the operator looks for a subsequence of the target that
+-- matches the input. If the target attribute of the comparison is a set
+-- ("SS", "NS", or "BS"), then the operator evaluates to true if it finds an
+-- exact match with any member of the set. CONTAINS is supported for lists:
+-- When evaluating "a CONTAINS b", "a" can be a list; however, "b" cannot be
+-- a set, a map, or a list. NOT_CONTAINS : Checks for absence of a
+-- subsequence, or absence of a value in a set. AttributeValueList can
+-- contain only one AttributeValue element of type String, Number, or Binary
+-- (not a set type). If the target attribute of the comparison is a String,
+-- then the operator checks for the absence of a substring match. If the
+-- target attribute of the comparison is Binary, then the operator checks
+-- for the absence of a subsequence of the target that matches the input. If
+-- the target attribute of the comparison is a set ("SS", "NS", or "BS"),
+-- then the operator evaluates to true if it does not find an exact match
+-- with any member of the set. NOT_CONTAINS is supported for lists: When
+-- evaluating "a NOT CONTAINS b", "a" can be a list; however, "b" cannot be
+-- a set, a map, or a list. BEGINS_WITH : Checks for a prefix.
+-- AttributeValueList can contain only one AttributeValue of type String or
+-- Binary (not a Number or a set type). The target attribute of the
+-- comparison must be of type String or Binary (not a Number or a set type).
+-- IN : Checks for matching elements within two sets. AttributeValueList can
+-- contain one or more AttributeValue elements of type String, Number, or
+-- Binary (not a set type). These attributes are compared against an
+-- existing set type attribute of an item. If any elements of the input set
+-- are present in the item attribute, the expression evaluates to true.
+-- BETWEEN : Greater than or equal to the first value, and less than or
+-- equal to the second value. AttributeValueList must contain two
+-- AttributeValue elements of the same type, either String, Number, or
+-- Binary (not a set type). A target attribute matches if the target value
+-- is greater than, or equal to, the first element and less than, or equal
+-- to, the second element. If an item contains an AttributeValue element of
+-- a different type than the one specified in the request, the value does
+-- not match. For example, {"S":"6"} does not compare to {"N":"6"}. Also,
+-- {"N":"6"} does not compare to {"NS":["6", "2", "1"]} For usage examples
+-- of AttributeValueList and ComparisonOperator, see Legacy Conditional
+-- Parameters in the Amazon DynamoDB Developer Guide. For backward
+-- compatibility with previous DynamoDB releases, the following parameters
+-- can be used instead of AttributeValueList and ComparisonOperator: Value -
+-- A value for DynamoDB to compare with an attribute. Exists - A Boolean
+-- value that causes DynamoDB to evaluate the value before attempting the
+-- conditional operation: If Exists is true, DynamoDB will check to see if
+-- that attribute value already exists in the table. If it is found, then
+-- the condition evaluates to true; otherwise the condition evaluate to
+-- false. If Exists is false, DynamoDB assumes that the attribute value does
+-- not exist in the table. If in fact the value does not exist, then the
+-- assumption is valid and the condition evaluates to true. If the value is
+-- found, despite the assumption that it does not exist, the condition
+-- evaluates to false. The Value and Exists parameters are incompatible with
+-- AttributeValueList and ComparisonOperator. Note that if you use both sets
+-- of parameters at once, DynamoDB will return a ValidationException
+-- exception.
+piExpected :: Lens' PutItem (HashMap Text ExpectedAttributeValue)
+piExpected = lens _piExpected (\s a -> s { _piExpected = a }) . _Map
+
+-- | One or more substitution tokens for simplifying complex expressions. The
+-- following are some use cases for an ExpressionAttributeNames value: To
+-- shorten an attribute name that is very long or unwieldy in an expression.
+-- To create a placeholder for repeating occurrences of an attribute name in
+-- an expression. To prevent special characters in an attribute name from
+-- being misinterpreted in an expression. Use the # character in an
+-- expression to dereference an attribute name. For example, consider the
+-- following expression: order.customerInfo.LastName = "Smith" OR
+-- order.customerInfo.LastName = "Jones" Now suppose that you specified the
+-- following for ExpressionAttributeNames:
+-- {"n":"order.customerInfo.LastName"} The expression can now be simplified
+-- as follows: #n = "Smith" OR #n = "Jones".
+piExpressionAttributeNames :: Lens' PutItem (HashMap Text Text)
+piExpressionAttributeNames =
+    lens _piExpressionAttributeNames
+        (\s a -> s { _piExpressionAttributeNames = a })
+            . _Map
+
+-- | One or more values that can be substituted in an expression. Use the :
+-- character in an expression to dereference an attribute value. For
+-- example, consider the following expression: ProductStatus IN
+-- ("Available","Backordered","Discontinued") Now suppose that you specified
+-- the following for ExpressionAttributeValues: { "a":{"S":"Available"},
+-- "b":{"S":"Backordered"}, "d":{"S":"Discontinued"} } The expression can
+-- now be simplified as follows: ProductStatus IN (:a,:b,:c).
+piExpressionAttributeValues :: Lens' PutItem (HashMap Text AttributeValue)
+piExpressionAttributeValues =
+    lens _piExpressionAttributeValues
+        (\s a -> s { _piExpressionAttributeValues = a })
+            . _Map
+
+-- | A map of attribute name/value pairs, one for each attribute. Only the
+-- primary key attributes are required; you can optionally provide other
+-- attribute name-value pairs for the item. You must provide all of the
+-- attributes for the primary key. For example, with a hash type primary
+-- key, you only need to specify the hash attribute. For a hash-and-range
+-- type primary key, you must specify both the hash attribute and the range
+-- attribute. If you specify any attributes that are part of an index key,
+-- then the data types for those attributes must match those of the schema
+-- in the table's attribute definition. For more information about primary
+-- keys, see Primary Key in the Amazon DynamoDB Developer Guide. Each
+-- element in the Item map is an AttributeValue object.
+piItem :: Lens' PutItem (HashMap Text AttributeValue)
+piItem = lens _piItem (\s a -> s { _piItem = a }) . _Map
+
+piReturnConsumedCapacity :: Lens' PutItem (Maybe Text)
+piReturnConsumedCapacity =
+    lens _piReturnConsumedCapacity
+        (\s a -> s { _piReturnConsumedCapacity = a })
+
+-- | A value that if set to SIZE, the response includes statistics about item
+-- collections, if any, that were modified during the operation are returned
+-- in the response. If set to NONE (the default), no statistics are
+-- returned.
+piReturnItemCollectionMetrics :: Lens' PutItem (Maybe Text)
+piReturnItemCollectionMetrics =
+    lens _piReturnItemCollectionMetrics
+        (\s a -> s { _piReturnItemCollectionMetrics = a })
+
+-- | Use ReturnValues if you want to get the item attributes as they appeared
+-- before they were updated with the PutItem request. For PutItem, the valid
+-- values are: NONE - If ReturnValues is not specified, or if its value is
+-- NONE, then nothing is returned. (This setting is the default for
+-- ReturnValues.) ALL_OLD - If PutItem overwrote an attribute name-value
+-- pair, then the content of the old item is returned.
+piReturnValues :: Lens' PutItem (Maybe Text)
+piReturnValues = lens _piReturnValues (\s a -> s { _piReturnValues = a })
+
+-- | The name of the table to contain the item.
+piTableName :: Lens' PutItem Text
+piTableName = lens _piTableName (\s a -> s { _piTableName = a })
+
+data PutItemResponse = PutItemResponse
+    { _pirAttributes            :: Map Text AttributeValue
+    , _pirConsumedCapacity      :: Maybe ConsumedCapacity
+    , _pirItemCollectionMetrics :: Maybe ItemCollectionMetrics
+    } deriving (Eq, Show)
+
+-- | 'PutItemResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'pirAttributes' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'pirConsumedCapacity' @::@ 'Maybe' 'ConsumedCapacity'
+--
+-- * 'pirItemCollectionMetrics' @::@ 'Maybe' 'ItemCollectionMetrics'
+--
+putItemResponse :: PutItemResponse
+putItemResponse = PutItemResponse
+    { _pirAttributes            = mempty
+    , _pirConsumedCapacity      = Nothing
+    , _pirItemCollectionMetrics = Nothing
+    }
+
+-- | The attribute values as they appeared before the PutItem operation, but
+-- only if ReturnValues is specified as ALL_OLD in the request. Each element
+-- consists of an attribute name and an attribute value.
+pirAttributes :: Lens' PutItemResponse (HashMap Text AttributeValue)
+pirAttributes = lens _pirAttributes (\s a -> s { _pirAttributes = a }) . _Map
+
+pirConsumedCapacity :: Lens' PutItemResponse (Maybe ConsumedCapacity)
+pirConsumedCapacity =
+    lens _pirConsumedCapacity (\s a -> s { _pirConsumedCapacity = a })
+
+-- | Information about item collections, if any, that were affected by the
+-- operation. ItemCollectionMetrics is only returned if the request asked
+-- for it. If the table does not have any local secondary indexes, this
+-- information is not returned in the response. Each ItemCollectionMetrics
+-- element consists of: ItemCollectionKey - The hash key value of the item
+-- collection. This is the same as the hash key of the item.
+-- SizeEstimateRange - An estimate of item collection size, in gigabytes.
+-- This value is a two-element array containing a lower bound and an upper
+-- bound for the estimate. The estimate includes the size of all the items
+-- in the table, plus the size of all attributes projected into all of the
+-- local secondary indexes on that table. Use this estimate to measure
+-- whether a local secondary index is approaching its size limit. The
+-- estimate is subject to change over time; therefore, do not rely on the
+-- precision or accuracy of the estimate.
+pirItemCollectionMetrics :: Lens' PutItemResponse (Maybe ItemCollectionMetrics)
+pirItemCollectionMetrics =
+    lens _pirItemCollectionMetrics
+        (\s a -> s { _pirItemCollectionMetrics = a })
+
+instance ToPath PutItem where
+    toPath = const "/"
+
+instance ToQuery PutItem where
+    toQuery = const mempty
+
+instance ToHeaders PutItem
+
+instance ToJSON PutItem where
+    toJSON PutItem{..} = object
+        [ "TableName"                   .= _piTableName
+        , "Item"                        .= _piItem
+        , "Expected"                    .= _piExpected
+        , "ReturnValues"                .= _piReturnValues
+        , "ReturnConsumedCapacity"      .= _piReturnConsumedCapacity
+        , "ReturnItemCollectionMetrics" .= _piReturnItemCollectionMetrics
+        , "ConditionalOperator"         .= _piConditionalOperator
+        , "ConditionExpression"         .= _piConditionExpression
+        , "ExpressionAttributeNames"    .= _piExpressionAttributeNames
+        , "ExpressionAttributeValues"   .= _piExpressionAttributeValues
+        ]
+
+instance AWSRequest PutItem where
+    type Sv PutItem = DynamoDB
+    type Rs PutItem = PutItemResponse
+
+    request  = post "PutItem"
+    response = jsonResponse
+
+instance FromJSON PutItemResponse where
+    parseJSON = withObject "PutItemResponse" $ \o -> PutItemResponse
+        <$> o .:  "Attributes"
+        <*> o .:? "ConsumedCapacity"
+        <*> o .:? "ItemCollectionMetrics"
diff --git a/gen/Network/AWS/DynamoDB/Query.hs b/gen/Network/AWS/DynamoDB/Query.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/Query.hs
@@ -0,0 +1,546 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.Query
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | A Query operation directly accesses items from a table using the table
+-- primary key, or from an index using the index key. You must provide a
+-- specific hash key value. You can narrow the scope of the query by using
+-- comparison operators on the range key value, or on the index key. You can
+-- use the ScanIndexForward parameter to get results in forward or reverse
+-- order, by range key or by index key. Queries that do not return results
+-- consume the minimum number of read capacity units for that type of read
+-- operation. If the total number of items meeting the query criteria exceeds
+-- the result set size limit of 1 MB, the query stops and results are returned
+-- to the user with LastEvaluatedKey to continue the query in a subsequent
+-- operation. Unlike a Scan operation, a Query operation never returns both an
+-- empty result set and a LastEvaluatedKey. The LastEvaluatedKey is only
+-- provided if the results exceed 1 MB, or if you have used Limit. You can
+-- query a table, a local secondary index, or a global secondary index. For a
+-- query on a table or on a local secondary index, you can set ConsistentRead
+-- to true and obtain a strongly consistent result. Global secondary indexes
+-- support eventually consistent reads only, so do not specify ConsistentRead
+-- when querying a global secondary index.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html>
+module Network.AWS.DynamoDB.Query
+    (
+    -- * Request
+      Query
+    -- ** Request constructor
+    , query
+    -- ** Request lenses
+    , qAttributesToGet
+    , qConditionalOperator
+    , qConsistentRead
+    , qExclusiveStartKey
+    , qExpressionAttributeNames
+    , qExpressionAttributeValues
+    , qFilterExpression
+    , qIndexName
+    , qKeyConditions
+    , qLimit
+    , qProjectionExpression
+    , qQueryFilter
+    , qReturnConsumedCapacity
+    , qScanIndexForward
+    , qSelect
+    , qTableName
+
+    -- * Response
+    , QueryResponse
+    -- ** Response constructor
+    , queryResponse
+    -- ** Response lenses
+    , qrConsumedCapacity
+    , qrCount
+    , qrItems
+    , qrLastEvaluatedKey
+    , qrScannedCount
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+data Query = Query
+    { _qAttributesToGet           :: List1 "AttributesToGet" Text
+    , _qConditionalOperator       :: Maybe Text
+    , _qConsistentRead            :: Maybe Bool
+    , _qExclusiveStartKey         :: Map Text AttributeValue
+    , _qExpressionAttributeNames  :: Map Text Text
+    , _qExpressionAttributeValues :: Map Text AttributeValue
+    , _qFilterExpression          :: Maybe Text
+    , _qIndexName                 :: Maybe Text
+    , _qKeyConditions             :: Map Text Condition
+    , _qLimit                     :: Maybe Nat
+    , _qProjectionExpression      :: Maybe Text
+    , _qQueryFilter               :: Map Text Condition
+    , _qReturnConsumedCapacity    :: Maybe Text
+    , _qScanIndexForward          :: Maybe Bool
+    , _qSelect                    :: Maybe Text
+    , _qTableName                 :: Text
+    } deriving (Eq, Show)
+
+-- | 'Query' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'qAttributesToGet' @::@ 'NonEmpty' 'Text'
+--
+-- * 'qConditionalOperator' @::@ 'Maybe' 'Text'
+--
+-- * 'qConsistentRead' @::@ 'Maybe' 'Bool'
+--
+-- * 'qExclusiveStartKey' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'qExpressionAttributeNames' @::@ 'HashMap' 'Text' 'Text'
+--
+-- * 'qExpressionAttributeValues' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'qFilterExpression' @::@ 'Maybe' 'Text'
+--
+-- * 'qIndexName' @::@ 'Maybe' 'Text'
+--
+-- * 'qKeyConditions' @::@ 'HashMap' 'Text' 'Condition'
+--
+-- * 'qLimit' @::@ 'Maybe' 'Natural'
+--
+-- * 'qProjectionExpression' @::@ 'Maybe' 'Text'
+--
+-- * 'qQueryFilter' @::@ 'HashMap' 'Text' 'Condition'
+--
+-- * 'qReturnConsumedCapacity' @::@ 'Maybe' 'Text'
+--
+-- * 'qScanIndexForward' @::@ 'Maybe' 'Bool'
+--
+-- * 'qSelect' @::@ 'Maybe' 'Text'
+--
+-- * 'qTableName' @::@ 'Text'
+--
+query :: Text -- ^ 'qTableName'
+      -> NonEmpty Text -- ^ 'qAttributesToGet'
+      -> Query
+query p1 p2 = Query
+    { _qTableName                 = p1
+    , _qAttributesToGet           = withIso _List1 (const id) p2
+    , _qIndexName                 = Nothing
+    , _qSelect                    = Nothing
+    , _qLimit                     = Nothing
+    , _qConsistentRead            = Nothing
+    , _qKeyConditions             = mempty
+    , _qQueryFilter               = mempty
+    , _qConditionalOperator       = Nothing
+    , _qScanIndexForward          = Nothing
+    , _qExclusiveStartKey         = mempty
+    , _qReturnConsumedCapacity    = Nothing
+    , _qProjectionExpression      = Nothing
+    , _qFilterExpression          = Nothing
+    , _qExpressionAttributeNames  = mempty
+    , _qExpressionAttributeValues = mempty
+    }
+
+-- | There is a newer parameter available. Use ProjectionExpression instead.
+-- Note that if you use AttributesToGet and ProjectionExpression at the same
+-- time, DynamoDB will return a ValidationException exception. This
+-- parameter allows you to retrieve lists or maps; however, it cannot
+-- retrieve individual list or map elements. The names of one or more
+-- attributes to retrieve. If no attribute names are specified, then all
+-- attributes will be returned. If any of the requested attributes are not
+-- found, they will not appear in the result. Note that AttributesToGet has
+-- no effect on provisioned throughput consumption. DynamoDB determines
+-- capacity units consumed based on item size, not on the amount of data
+-- that is returned to an application. You cannot use both AttributesToGet
+-- and Select together in a Query request, unless the value for Select is
+-- SPECIFIC_ATTRIBUTES. (This usage is equivalent to specifying
+-- AttributesToGet without any value for Select.) If you query a local
+-- secondary index and request only attributes that are projected into that
+-- index, the operation will read only the index and not the table. If any
+-- of the requested attributes are not projected into the local secondary
+-- index, DynamoDB will fetch each of these attributes from the parent
+-- table. This extra fetching incurs additional throughput cost and latency.
+-- If you query a global secondary index, you can only request attributes
+-- that are projected into the index. Global secondary index queries cannot
+-- fetch attributes from the parent table.
+qAttributesToGet :: Lens' Query (NonEmpty Text)
+qAttributesToGet = lens _qAttributesToGet (\s a -> s { _qAttributesToGet = a }) . _List1
+
+-- | There is a newer parameter available. Use ConditionExpression instead.
+-- Note that if you use ConditionalOperator and ConditionExpression at the
+-- same time, DynamoDB will return a ValidationException exception. This
+-- parameter does not support lists or maps. A logical operator to apply to
+-- the conditions in the QueryFilter map: AND - If all of the conditions
+-- evaluate to true, then the entire map evaluates to true. OR - If at least
+-- one of the conditions evaluate to true, then the entire map evaluates to
+-- true. If you omit ConditionalOperator, then AND is the default. The
+-- operation will succeed only if the entire map evaluates to true.
+qConditionalOperator :: Lens' Query (Maybe Text)
+qConditionalOperator =
+    lens _qConditionalOperator (\s a -> s { _qConditionalOperator = a })
+
+-- | A value that if set to true, then the operation uses strongly consistent
+-- reads; otherwise, eventually consistent reads are used. Strongly
+-- consistent reads are not supported on global secondary indexes. If you
+-- query a global secondary index with ConsistentRead set to true, you will
+-- receive an error message.
+qConsistentRead :: Lens' Query (Maybe Bool)
+qConsistentRead = lens _qConsistentRead (\s a -> s { _qConsistentRead = a })
+
+-- | The primary key of the first item that this operation will evaluate. Use
+-- the value that was returned for LastEvaluatedKey in the previous
+-- operation. The data type for ExclusiveStartKey must be String, Number or
+-- Binary. No set data types are allowed.
+qExclusiveStartKey :: Lens' Query (HashMap Text AttributeValue)
+qExclusiveStartKey =
+    lens _qExclusiveStartKey (\s a -> s { _qExclusiveStartKey = a })
+        . _Map
+
+-- | One or more substitution tokens for simplifying complex expressions. The
+-- following are some use cases for an ExpressionAttributeNames value: To
+-- shorten an attribute name that is very long or unwieldy in an expression.
+-- To create a placeholder for repeating occurrences of an attribute name in
+-- an expression. To prevent special characters in an attribute name from
+-- being misinterpreted in an expression. Use the # character in an
+-- expression to dereference an attribute name. For example, consider the
+-- following expression: order.customerInfo.LastName = "Smith" OR
+-- order.customerInfo.LastName = "Jones" Now suppose that you specified the
+-- following for ExpressionAttributeNames:
+-- {"n":"order.customerInfo.LastName"} The expression can now be simplified
+-- as follows: #n = "Smith" OR #n = "Jones".
+qExpressionAttributeNames :: Lens' Query (HashMap Text Text)
+qExpressionAttributeNames =
+    lens _qExpressionAttributeNames
+        (\s a -> s { _qExpressionAttributeNames = a })
+            . _Map
+
+-- | One or more values that can be substituted in an expression. Use the :
+-- character in an expression to dereference an attribute value. For
+-- example, consider the following expression: ProductStatus IN
+-- ("Available","Backordered","Discontinued") Now suppose that you specified
+-- the following for ExpressionAttributeValues: { "a":{"S":"Available"},
+-- "b":{"S":"Backordered"}, "d":{"S":"Discontinued"} } The expression can
+-- now be simplified as follows: ProductStatus IN (:a,:b,:c).
+qExpressionAttributeValues :: Lens' Query (HashMap Text AttributeValue)
+qExpressionAttributeValues =
+    lens _qExpressionAttributeValues
+        (\s a -> s { _qExpressionAttributeValues = a })
+            . _Map
+
+-- | A condition that evaluates the query results and returns only the desired
+-- values. The condition you specify is applied to the items queried; any
+-- items that do not match the expression are not returned.
+qFilterExpression :: Lens' Query (Maybe Text)
+qFilterExpression =
+    lens _qFilterExpression (\s a -> s { _qFilterExpression = a })
+
+-- | The name of an index to query. This index can be any local secondary
+-- index or global secondary index on the table.
+qIndexName :: Lens' Query (Maybe Text)
+qIndexName = lens _qIndexName (\s a -> s { _qIndexName = a })
+
+-- | The selection criteria for the query. For a query on a table, you can
+-- have conditions only on the table primary key attributes. You must
+-- specify the hash key attribute name and value as an EQ condition. You can
+-- optionally specify a second condition, referring to the range key
+-- attribute. For a query on an index, you can have conditions only on the
+-- index key attributes. You must specify the index hash attribute name and
+-- value as an EQ condition. You can optionally specify a second condition,
+-- referring to the index key range attribute. Each KeyConditions element
+-- consists of an attribute name to compare, along with the following:
+-- AttributeValueList - One or more values to evaluate against the supplied
+-- attribute. The number of values in the list depends on the
+-- ComparisonOperator being used. For type Number, value comparisons are
+-- numeric. String value comparisons for greater than, equals, or less than
+-- are based on ASCII character code values. For example, a is greater than
+-- A, and aa is greater than B. For a list of code values, see
+-- http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters. For
+-- Binary, DynamoDB treats each byte of the binary data as unsigned when it
+-- compares binary values, for example when evaluating query expressions.
+-- ComparisonOperator - A comparator for evaluating attributes, for example,
+-- equals, greater than, less than, and so on. For KeyConditions, only the
+-- following comparison operators are supported: EQ | LE | LT | GE | GT |
+-- BEGINS_WITH | BETWEEN The following are descriptions of these comparison
+-- operators. EQ : Equal. AttributeValueList can contain only one
+-- AttributeValue of type String, Number, or Binary (not a set type). If an
+-- item contains an AttributeValue element of a different type than the one
+-- specified in the request, the value does not match. For example,
+-- {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not equal
+-- {"NS":["6", "2", "1"]}. LE : Less than or equal. AttributeValueList can
+-- contain only one AttributeValue element of type String, Number, or Binary
+-- (not a set type). If an item contains an AttributeValue element of a
+-- different type than the one specified in the request, the value does not
+-- match. For example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"}
+-- does not compare to {"NS":["6", "2", "1"]}. LT : Less than.
+-- AttributeValueList can contain only one AttributeValue of type String,
+-- Number, or Binary (not a set type). If an item contains an AttributeValue
+-- element of a different type than the one specified in the request, the
+-- value does not match. For example, {"S":"6"} does not equal {"N":"6"}.
+-- Also, {"N":"6"} does not compare to {"NS":["6", "2", "1"]}. GE : Greater
+-- than or equal. AttributeValueList can contain only one AttributeValue
+-- element of type String, Number, or Binary (not a set type). If an item
+-- contains an AttributeValue element of a different type than the one
+-- specified in the request, the value does not match. For example,
+-- {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not compare to
+-- {"NS":["6", "2", "1"]}. GT : Greater than. AttributeValueList can contain
+-- only one AttributeValue element of type String, Number, or Binary (not a
+-- set type). If an item contains an AttributeValue element of a different
+-- type than the one specified in the request, the value does not match. For
+-- example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not
+-- compare to {"NS":["6", "2", "1"]}. BEGINS_WITH : Checks for a prefix.
+-- AttributeValueList can contain only one AttributeValue of type String or
+-- Binary (not a Number or a set type). The target attribute of the
+-- comparison must be of type String or Binary (not a Number or a set type).
+-- BETWEEN : Greater than or equal to the first value, and less than or
+-- equal to the second value. AttributeValueList must contain two
+-- AttributeValue elements of the same type, either String, Number, or
+-- Binary (not a set type). A target attribute matches if the target value
+-- is greater than, or equal to, the first element and less than, or equal
+-- to, the second element. If an item contains an AttributeValue element of
+-- a different type than the one specified in the request, the value does
+-- not match. For example, {"S":"6"} does not compare to {"N":"6"}. Also,
+-- {"N":"6"} does not compare to {"NS":["6", "2", "1"]} For usage examples
+-- of AttributeValueList and ComparisonOperator, see Legacy Conditional
+-- Parameters in the Amazon DynamoDB Developer Guide.
+qKeyConditions :: Lens' Query (HashMap Text Condition)
+qKeyConditions = lens _qKeyConditions (\s a -> s { _qKeyConditions = a }) . _Map
+
+-- | The maximum number of items to evaluate (not necessarily the number of
+-- matching items). If DynamoDB processes the number of items up to the
+-- limit while processing the results, it stops the operation and returns
+-- the matching values up to that point, and a key in LastEvaluatedKey to
+-- apply in a subsequent operation, so that you can pick up where you left
+-- off. Also, if the processed data set size exceeds 1 MB before DynamoDB
+-- reaches this limit, it stops the operation and returns the matching
+-- values up to the limit, and a key in LastEvaluatedKey to apply in a
+-- subsequent operation to continue the operation. For more information, see
+-- Query and Scan in the Amazon DynamoDB Developer Guide.
+qLimit :: Lens' Query (Maybe Natural)
+qLimit = lens _qLimit (\s a -> s { _qLimit = a }) . mapping _Nat
+
+-- | One or more attributes to retrieve from the table. These attributes can
+-- include scalars, sets, or elements of a JSON document. The attributes in
+-- the expression must be separated by commas. If no attribute names are
+-- specified, then all attributes will be returned. If any of the requested
+-- attributes are not found, they will not appear in the result.
+qProjectionExpression :: Lens' Query (Maybe Text)
+qProjectionExpression =
+    lens _qProjectionExpression (\s a -> s { _qProjectionExpression = a })
+
+-- | There is a newer parameter available. Use FilterExpression instead. Note
+-- that if you use QueryFilter and FilterExpression at the same time,
+-- DynamoDB will return a ValidationException exception. This parameter does
+-- not support lists or maps. A condition that evaluates the query results
+-- and returns only the desired values. If you specify more than one
+-- condition in the QueryFilter map, then by default all of the conditions
+-- must evaluate to true. In other words, the conditions are ANDed together.
+-- (You can use the ConditionalOperator parameter to OR the conditions
+-- instead. If you do this, then at least one of the conditions must
+-- evaluate to true, rather than all of them.) Each QueryFilter element
+-- consists of an attribute name to compare, along with the following:
+-- AttributeValueList - One or more values to evaluate against the supplied
+-- attribute. The number of values in the list depends on the operator
+-- specified in ComparisonOperator. For type Number, value comparisons are
+-- numeric. String value comparisons for greater than, equals, or less than
+-- are based on ASCII character code values. For example, a is greater than
+-- A, and aa is greater than B. For a list of code values, see
+-- http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters. For type
+-- Binary, DynamoDB treats each byte of the binary data as unsigned when it
+-- compares binary values, for example when evaluating query expressions.
+-- For information on specifying data types in JSON, see JSON Data Format in
+-- the Amazon DynamoDB Developer Guide. ComparisonOperator - A comparator
+-- for evaluating attributes. For example, equals, greater than, less than,
+-- etc. The following comparison operators are available: EQ | NE | LE | LT
+-- | GE | GT | NOT_NULL | NULL | CONTAINS | NOT_CONTAINS | BEGINS_WITH | IN
+-- | BETWEEN For complete descriptions of all comparison operators, see
+-- API_Condition.html.
+qQueryFilter :: Lens' Query (HashMap Text Condition)
+qQueryFilter = lens _qQueryFilter (\s a -> s { _qQueryFilter = a }) . _Map
+
+qReturnConsumedCapacity :: Lens' Query (Maybe Text)
+qReturnConsumedCapacity =
+    lens _qReturnConsumedCapacity (\s a -> s { _qReturnConsumedCapacity = a })
+
+-- | A value that specifies ascending (true) or descending (false) traversal
+-- of the index. DynamoDB returns results reflecting the requested order
+-- determined by the range key. If the data type is Number, the results are
+-- returned in numeric order. For type String, the results are returned in
+-- order of ASCII character code values. For type Binary, DynamoDB treats
+-- each byte of the binary data as unsigned when it compares binary values.
+-- If ScanIndexForward is not specified, the results are returned in
+-- ascending order.
+qScanIndexForward :: Lens' Query (Maybe Bool)
+qScanIndexForward =
+    lens _qScanIndexForward (\s a -> s { _qScanIndexForward = a })
+
+-- | The attributes to be returned in the result. You can retrieve all item
+-- attributes, specific item attributes, the count of matching items, or in
+-- the case of an index, some or all of the attributes projected into the
+-- index. ALL_ATTRIBUTES - Returns all of the item attributes from the
+-- specified table or index. If you query a local secondary index, then for
+-- each matching item in the index DynamoDB will fetch the entire item from
+-- the parent table. If the index is configured to project all item
+-- attributes, then all of the data can be obtained from the local secondary
+-- index, and no fetching is required. ALL_PROJECTED_ATTRIBUTES - Allowed
+-- only when querying an index. Retrieves all attributes that have been
+-- projected into the index. If the index is configured to project all
+-- attributes, this return value is equivalent to specifying ALL_ATTRIBUTES.
+-- COUNT - Returns the number of matching items, rather than the matching
+-- items themselves. SPECIFIC_ATTRIBUTES - Returns only the attributes
+-- listed in AttributesToGet. This return value is equivalent to specifying
+-- AttributesToGet without specifying any value for Select. If you query a
+-- local secondary index and request only attributes that are projected into
+-- that index, the operation will read only the index and not the table. If
+-- any of the requested attributes are not projected into the local
+-- secondary index, DynamoDB will fetch each of these attributes from the
+-- parent table. This extra fetching incurs additional throughput cost and
+-- latency. If you query a global secondary index, you can only request
+-- attributes that are projected into the index. Global secondary index
+-- queries cannot fetch attributes from the parent table. If neither Select
+-- nor AttributesToGet are specified, DynamoDB defaults to ALL_ATTRIBUTES
+-- when accessing a table, and ALL_PROJECTED_ATTRIBUTES when accessing an
+-- index. You cannot use both Select and AttributesToGet together in a
+-- single request, unless the value for Select is SPECIFIC_ATTRIBUTES. (This
+-- usage is equivalent to specifying AttributesToGet without any value for
+-- Select.).
+qSelect :: Lens' Query (Maybe Text)
+qSelect = lens _qSelect (\s a -> s { _qSelect = a })
+
+-- | The name of the table containing the requested items.
+qTableName :: Lens' Query Text
+qTableName = lens _qTableName (\s a -> s { _qTableName = a })
+
+data QueryResponse = QueryResponse
+    { _qrConsumedCapacity :: Maybe ConsumedCapacity
+    , _qrCount            :: Maybe Int
+    , _qrItems            :: List "Items" (Map Text AttributeValue)
+    , _qrLastEvaluatedKey :: Map Text AttributeValue
+    , _qrScannedCount     :: Maybe Int
+    } deriving (Eq, Show)
+
+-- | 'QueryResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'qrConsumedCapacity' @::@ 'Maybe' 'ConsumedCapacity'
+--
+-- * 'qrCount' @::@ 'Maybe' 'Int'
+--
+-- * 'qrItems' @::@ ['HashMap' 'Text' 'AttributeValue']
+--
+-- * 'qrLastEvaluatedKey' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'qrScannedCount' @::@ 'Maybe' 'Int'
+--
+queryResponse :: QueryResponse
+queryResponse = QueryResponse
+    { _qrItems            = mempty
+    , _qrCount            = Nothing
+    , _qrScannedCount     = Nothing
+    , _qrLastEvaluatedKey = mempty
+    , _qrConsumedCapacity = Nothing
+    }
+
+qrConsumedCapacity :: Lens' QueryResponse (Maybe ConsumedCapacity)
+qrConsumedCapacity =
+    lens _qrConsumedCapacity (\s a -> s { _qrConsumedCapacity = a })
+
+-- | The number of items in the response. If you used a QueryFilter in the
+-- request, then Count is the number of items returned after the filter was
+-- applied, and ScannedCount is the number of matching items before&gt; the
+-- filter was applied. If you did not use a filter in the request, then
+-- Count and ScannedCount are the same.
+qrCount :: Lens' QueryResponse (Maybe Int)
+qrCount = lens _qrCount (\s a -> s { _qrCount = a })
+
+-- | An array of item attributes that match the query criteria. Each element
+-- in this array consists of an attribute name and the value for that
+-- attribute.
+qrItems :: Lens' QueryResponse [HashMap Text AttributeValue]
+qrItems = lens _qrItems (\s a -> s { _qrItems = a }) . _List
+
+-- | The primary key of the item where the operation stopped, inclusive of the
+-- previous result set. Use this value to start a new operation, excluding
+-- this value in the new request. If LastEvaluatedKey is empty, then the
+-- "last page" of results has been processed and there is no more data to be
+-- retrieved. If LastEvaluatedKey is not empty, it does not necessarily mean
+-- that there is more data in the result set. The only way to know when you
+-- have reached the end of the result set is when LastEvaluatedKey is empty.
+qrLastEvaluatedKey :: Lens' QueryResponse (HashMap Text AttributeValue)
+qrLastEvaluatedKey =
+    lens _qrLastEvaluatedKey (\s a -> s { _qrLastEvaluatedKey = a })
+        . _Map
+
+-- | The number of items evaluated, before any QueryFilter is applied. A high
+-- ScannedCount value with few, or no, Count results indicates an
+-- inefficient Query operation. For more information, see Count and
+-- ScannedCount in the Amazon DynamoDB Developer Guide. If you did not use a
+-- filter in the request, then ScannedCount is the same as Count.
+qrScannedCount :: Lens' QueryResponse (Maybe Int)
+qrScannedCount = lens _qrScannedCount (\s a -> s { _qrScannedCount = a })
+
+instance ToPath Query where
+    toPath = const "/"
+
+instance ToQuery Query where
+    toQuery = const mempty
+
+instance ToHeaders Query
+
+instance ToJSON Query where
+    toJSON Query{..} = object
+        [ "TableName"                 .= _qTableName
+        , "IndexName"                 .= _qIndexName
+        , "Select"                    .= _qSelect
+        , "AttributesToGet"           .= _qAttributesToGet
+        , "Limit"                     .= _qLimit
+        , "ConsistentRead"            .= _qConsistentRead
+        , "KeyConditions"             .= _qKeyConditions
+        , "QueryFilter"               .= _qQueryFilter
+        , "ConditionalOperator"       .= _qConditionalOperator
+        , "ScanIndexForward"          .= _qScanIndexForward
+        , "ExclusiveStartKey"         .= _qExclusiveStartKey
+        , "ReturnConsumedCapacity"    .= _qReturnConsumedCapacity
+        , "ProjectionExpression"      .= _qProjectionExpression
+        , "FilterExpression"          .= _qFilterExpression
+        , "ExpressionAttributeNames"  .= _qExpressionAttributeNames
+        , "ExpressionAttributeValues" .= _qExpressionAttributeValues
+        ]
+
+instance AWSRequest Query where
+    type Sv Query = DynamoDB
+    type Rs Query = QueryResponse
+
+    request  = post "Query"
+    response = jsonResponse
+
+instance FromJSON QueryResponse where
+    parseJSON = withObject "QueryResponse" $ \o -> QueryResponse
+        <$> o .:? "ConsumedCapacity"
+        <*> o .:? "Count"
+        <*> o .:  "Items"
+        <*> o .:  "LastEvaluatedKey"
+        <*> o .:? "ScannedCount"
+
+instance AWSPager Query where
+    page rq rs
+        | stop (rq ^. qExclusiveStartKey) = Nothing
+        | otherwise = Just $ rq
+            & qExclusiveStartKey .~ rs ^. qrLastEvaluatedKey
diff --git a/gen/Network/AWS/DynamoDB/Scan.hs b/gen/Network/AWS/DynamoDB/Scan.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/Scan.hs
@@ -0,0 +1,435 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.Scan
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | The Scan operation returns one or more items and item attributes by
+-- accessing every item in the table. To have DynamoDB return fewer items, you
+-- can provide a ScanFilter operation. If the total number of scanned items
+-- exceeds the maximum data set size limit of 1 MB, the scan stops and results
+-- are returned to the user as a LastEvaluatedKey value to continue the scan
+-- in a subsequent operation. The results also include the number of items
+-- exceeding the limit. A scan can result in no table data meeting the filter
+-- criteria. The result set is eventually consistent. By default, Scan
+-- operations proceed sequentially; however, for faster performance on large
+-- tables, applications can request a parallel Scan operation by specifying
+-- the Segment and TotalSegments parameters. For more information, see
+-- Parallel Scan in the Amazon DynamoDB Developer Guide.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html>
+module Network.AWS.DynamoDB.Scan
+    (
+    -- * Request
+      Scan
+    -- ** Request constructor
+    , scan
+    -- ** Request lenses
+    , sAttributesToGet
+    , sConditionalOperator
+    , sExclusiveStartKey
+    , sExpressionAttributeNames
+    , sExpressionAttributeValues
+    , sFilterExpression
+    , sLimit
+    , sProjectionExpression
+    , sReturnConsumedCapacity
+    , sScanFilter
+    , sSegment
+    , sSelect
+    , sTableName
+    , sTotalSegments
+
+    -- * Response
+    , ScanResponse
+    -- ** Response constructor
+    , scanResponse
+    -- ** Response lenses
+    , srConsumedCapacity
+    , srCount
+    , srItems
+    , srLastEvaluatedKey
+    , srScannedCount
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+data Scan = Scan
+    { _sAttributesToGet           :: List1 "AttributesToGet" Text
+    , _sConditionalOperator       :: Maybe Text
+    , _sExclusiveStartKey         :: Map Text AttributeValue
+    , _sExpressionAttributeNames  :: Map Text Text
+    , _sExpressionAttributeValues :: Map Text AttributeValue
+    , _sFilterExpression          :: Maybe Text
+    , _sLimit                     :: Maybe Nat
+    , _sProjectionExpression      :: Maybe Text
+    , _sReturnConsumedCapacity    :: Maybe Text
+    , _sScanFilter                :: Map Text Condition
+    , _sSegment                   :: Maybe Nat
+    , _sSelect                    :: Maybe Text
+    , _sTableName                 :: Text
+    , _sTotalSegments             :: Maybe Nat
+    } deriving (Eq, Show)
+
+-- | 'Scan' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'sAttributesToGet' @::@ 'NonEmpty' 'Text'
+--
+-- * 'sConditionalOperator' @::@ 'Maybe' 'Text'
+--
+-- * 'sExclusiveStartKey' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'sExpressionAttributeNames' @::@ 'HashMap' 'Text' 'Text'
+--
+-- * 'sExpressionAttributeValues' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'sFilterExpression' @::@ 'Maybe' 'Text'
+--
+-- * 'sLimit' @::@ 'Maybe' 'Natural'
+--
+-- * 'sProjectionExpression' @::@ 'Maybe' 'Text'
+--
+-- * 'sReturnConsumedCapacity' @::@ 'Maybe' 'Text'
+--
+-- * 'sScanFilter' @::@ 'HashMap' 'Text' 'Condition'
+--
+-- * 'sSegment' @::@ 'Maybe' 'Natural'
+--
+-- * 'sSelect' @::@ 'Maybe' 'Text'
+--
+-- * 'sTableName' @::@ 'Text'
+--
+-- * 'sTotalSegments' @::@ 'Maybe' 'Natural'
+--
+scan :: Text -- ^ 'sTableName'
+     -> NonEmpty Text -- ^ 'sAttributesToGet'
+     -> Scan
+scan p1 p2 = Scan
+    { _sTableName                 = p1
+    , _sAttributesToGet           = withIso _List1 (const id) p2
+    , _sLimit                     = Nothing
+    , _sSelect                    = Nothing
+    , _sScanFilter                = mempty
+    , _sConditionalOperator       = Nothing
+    , _sExclusiveStartKey         = mempty
+    , _sReturnConsumedCapacity    = Nothing
+    , _sTotalSegments             = Nothing
+    , _sSegment                   = Nothing
+    , _sProjectionExpression      = Nothing
+    , _sFilterExpression          = Nothing
+    , _sExpressionAttributeNames  = mempty
+    , _sExpressionAttributeValues = mempty
+    }
+
+-- | There is a newer parameter available. Use ProjectionExpression instead.
+-- Note that if you use AttributesToGet and ProjectionExpression at the same
+-- time, DynamoDB will return a ValidationException exception. This
+-- parameter allows you to retrieve lists or maps; however, it cannot
+-- retrieve individual list or map elements. The names of one or more
+-- attributes to retrieve. If no attribute names are specified, then all
+-- attributes will be returned. If any of the requested attributes are not
+-- found, they will not appear in the result. Note that AttributesToGet has
+-- no effect on provisioned throughput consumption. DynamoDB determines
+-- capacity units consumed based on item size, not on the amount of data
+-- that is returned to an application.
+sAttributesToGet :: Lens' Scan (NonEmpty Text)
+sAttributesToGet = lens _sAttributesToGet (\s a -> s { _sAttributesToGet = a }) . _List1
+
+-- | There is a newer parameter available. Use ConditionExpression instead.
+-- Note that if you use ConditionalOperator and ConditionExpression at the
+-- same time, DynamoDB will return a ValidationException exception. This
+-- parameter does not support lists or maps. A logical operator to apply to
+-- the conditions in the ScanFilter map: AND - If all of the conditions
+-- evaluate to true, then the entire map evaluates to true. OR - If at least
+-- one of the conditions evaluate to true, then the entire map evaluates to
+-- true. If you omit ConditionalOperator, then AND is the default. The
+-- operation will succeed only if the entire map evaluates to true.
+sConditionalOperator :: Lens' Scan (Maybe Text)
+sConditionalOperator =
+    lens _sConditionalOperator (\s a -> s { _sConditionalOperator = a })
+
+-- | The primary key of the first item that this operation will evaluate. Use
+-- the value that was returned for LastEvaluatedKey in the previous
+-- operation. The data type for ExclusiveStartKey must be String, Number or
+-- Binary. No set data types are allowed. In a parallel scan, a Scan request
+-- that includes ExclusiveStartKey must specify the same segment whose
+-- previous Scan returned the corresponding value of LastEvaluatedKey.
+sExclusiveStartKey :: Lens' Scan (HashMap Text AttributeValue)
+sExclusiveStartKey =
+    lens _sExclusiveStartKey (\s a -> s { _sExclusiveStartKey = a })
+        . _Map
+
+-- | One or more substitution tokens for simplifying complex expressions. The
+-- following are some use cases for an ExpressionAttributeNames value: To
+-- shorten an attribute name that is very long or unwieldy in an expression.
+-- To create a placeholder for repeating occurrences of an attribute name in
+-- an expression. To prevent special characters in an attribute name from
+-- being misinterpreted in an expression. Use the # character in an
+-- expression to dereference an attribute name. For example, consider the
+-- following expression: order.customerInfo.LastName = "Smith" OR
+-- order.customerInfo.LastName = "Jones" Now suppose that you specified the
+-- following for ExpressionAttributeNames:
+-- {"n":"order.customerInfo.LastName"} The expression can now be simplified
+-- as follows: #n = "Smith" OR #n = "Jones".
+sExpressionAttributeNames :: Lens' Scan (HashMap Text Text)
+sExpressionAttributeNames =
+    lens _sExpressionAttributeNames
+        (\s a -> s { _sExpressionAttributeNames = a })
+            . _Map
+
+-- | One or more values that can be substituted in an expression. Use the :
+-- character in an expression to dereference an attribute value. For
+-- example, consider the following expression: ProductStatus IN
+-- ("Available","Backordered","Discontinued") Now suppose that you specified
+-- the following for ExpressionAttributeValues: { "a":{"S":"Available"},
+-- "b":{"S":"Backordered"}, "d":{"S":"Discontinued"} } The expression can
+-- now be simplified as follows: ProductStatus IN (:a,:b,:c).
+sExpressionAttributeValues :: Lens' Scan (HashMap Text AttributeValue)
+sExpressionAttributeValues =
+    lens _sExpressionAttributeValues
+        (\s a -> s { _sExpressionAttributeValues = a })
+            . _Map
+
+-- | A condition that evaluates the scan results and returns only the desired
+-- values. The condition you specify is applied to the items scanned; any
+-- items that do not match the expression are not returned.
+sFilterExpression :: Lens' Scan (Maybe Text)
+sFilterExpression =
+    lens _sFilterExpression (\s a -> s { _sFilterExpression = a })
+
+-- | The maximum number of items to evaluate (not necessarily the number of
+-- matching items). If DynamoDB processes the number of items up to the
+-- limit while processing the results, it stops the operation and returns
+-- the matching values up to that point, and a key in LastEvaluatedKey to
+-- apply in a subsequent operation, so that you can pick up where you left
+-- off. Also, if the processed data set size exceeds 1 MB before DynamoDB
+-- reaches this limit, it stops the operation and returns the matching
+-- values up to the limit, and a key in LastEvaluatedKey to apply in a
+-- subsequent operation to continue the operation. For more information, see
+-- Query and Scan in the Amazon DynamoDB Developer Guide.
+sLimit :: Lens' Scan (Maybe Natural)
+sLimit = lens _sLimit (\s a -> s { _sLimit = a }) . mapping _Nat
+
+-- | One or more attributes to retrieve from the table. These attributes can
+-- include scalars, sets, or elements of a JSON document. The attributes in
+-- the expression must be separated by commas. If no attribute names are
+-- specified, then all attributes will be returned. If any of the requested
+-- attributes are not found, they will not appear in the result.
+sProjectionExpression :: Lens' Scan (Maybe Text)
+sProjectionExpression =
+    lens _sProjectionExpression (\s a -> s { _sProjectionExpression = a })
+
+sReturnConsumedCapacity :: Lens' Scan (Maybe Text)
+sReturnConsumedCapacity =
+    lens _sReturnConsumedCapacity (\s a -> s { _sReturnConsumedCapacity = a })
+
+-- | There is a newer parameter available. Use FilterExpression instead. Note
+-- that if you use ScanFilter and FilterExpression at the same time,
+-- DynamoDB will return a ValidationException exception. This parameter does
+-- not support lists or maps. A condition that evaluates the scan results
+-- and returns only the desired values. If you specify more than one
+-- condition in the ScanFilter map, then by default all of the conditions
+-- must evaluate to true. In other words, the conditions are ANDed together.
+-- (You can use the ConditionalOperator parameter to OR the conditions
+-- instead. If you do this, then at least one of the conditions must
+-- evaluate to true, rather than all of them.) Each ScanFilter element
+-- consists of an attribute name to compare, along with the following:
+-- AttributeValueList - One or more values to evaluate against the supplied
+-- attribute. The number of values in the list depends on the operator
+-- specified in ComparisonOperator . For type Number, value comparisons are
+-- numeric. String value comparisons for greater than, equals, or less than
+-- are based on ASCII character code values. For example, a is greater than
+-- A, and aa is greater than B. For a list of code values, see
+-- http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters. For
+-- Binary, DynamoDB treats each byte of the binary data as unsigned when it
+-- compares binary values, for example when evaluating query expressions.
+-- For information on specifying data types in JSON, see JSON Data Format in
+-- the Amazon DynamoDB Developer Guide. ComparisonOperator - A comparator
+-- for evaluating attributes. For example, equals, greater than, less than,
+-- etc. The following comparison operators are available: EQ | NE | LE | LT
+-- | GE | GT | NOT_NULL | NULL | CONTAINS | NOT_CONTAINS | BEGINS_WITH | IN
+-- | BETWEEN For complete descriptions of all comparison operators, see
+-- Condition.
+sScanFilter :: Lens' Scan (HashMap Text Condition)
+sScanFilter = lens _sScanFilter (\s a -> s { _sScanFilter = a }) . _Map
+
+-- | For a parallel Scan request, Segment identifies an individual segment to
+-- be scanned by an application worker. Segment IDs are zero-based, so the
+-- first segment is always 0. For example, if you want to scan a table using
+-- four application threads, the first thread specifies a Segment value of
+-- 0, the second thread specifies 1, and so on. The value of
+-- LastEvaluatedKey returned from a parallel Scan request must be used as
+-- ExclusiveStartKey with the same segment ID in a subsequent Scan
+-- operation. The value for Segment must be greater than or equal to 0, and
+-- less than the value provided for TotalSegments. If you specify Segment,
+-- you must also specify TotalSegments.
+sSegment :: Lens' Scan (Maybe Natural)
+sSegment = lens _sSegment (\s a -> s { _sSegment = a }) . mapping _Nat
+
+-- | The attributes to be returned in the result. You can retrieve all item
+-- attributes, specific item attributes, or the count of matching items.
+-- ALL_ATTRIBUTES - Returns all of the item attributes. COUNT - Returns the
+-- number of matching items, rather than the matching items themselves.
+-- SPECIFIC_ATTRIBUTES - Returns only the attributes listed in
+-- AttributesToGet. This return value is equivalent to specifying
+-- AttributesToGet without specifying any value for Select. If neither
+-- Select nor AttributesToGet are specified, DynamoDB defaults to
+-- ALL_ATTRIBUTES. You cannot use both AttributesToGet and Select together
+-- in a single request, unless the value for Select is SPECIFIC_ATTRIBUTES.
+-- (This usage is equivalent to specifying AttributesToGet without any value
+-- for Select.).
+sSelect :: Lens' Scan (Maybe Text)
+sSelect = lens _sSelect (\s a -> s { _sSelect = a })
+
+-- | The name of the table containing the requested items.
+sTableName :: Lens' Scan Text
+sTableName = lens _sTableName (\s a -> s { _sTableName = a })
+
+-- | For a parallel Scan request, TotalSegments represents the total number of
+-- segments into which the Scan operation will be divided. The value of
+-- TotalSegments corresponds to the number of application workers that will
+-- perform the parallel scan. For example, if you want to scan a table using
+-- four application threads, specify a TotalSegments value of 4. The value
+-- for TotalSegments must be greater than or equal to 1, and less than or
+-- equal to 1000000. If you specify a TotalSegments value of 1, the Scan
+-- operation will be sequential rather than parallel. If you specify
+-- TotalSegments, you must also specify Segment.
+sTotalSegments :: Lens' Scan (Maybe Natural)
+sTotalSegments = lens _sTotalSegments (\s a -> s { _sTotalSegments = a }) . mapping _Nat
+
+data ScanResponse = ScanResponse
+    { _srConsumedCapacity :: Maybe ConsumedCapacity
+    , _srCount            :: Maybe Int
+    , _srItems            :: List "Items" (Map Text AttributeValue)
+    , _srLastEvaluatedKey :: Map Text AttributeValue
+    , _srScannedCount     :: Maybe Int
+    } deriving (Eq, Show)
+
+-- | 'ScanResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'srConsumedCapacity' @::@ 'Maybe' 'ConsumedCapacity'
+--
+-- * 'srCount' @::@ 'Maybe' 'Int'
+--
+-- * 'srItems' @::@ ['HashMap' 'Text' 'AttributeValue']
+--
+-- * 'srLastEvaluatedKey' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'srScannedCount' @::@ 'Maybe' 'Int'
+--
+scanResponse :: ScanResponse
+scanResponse = ScanResponse
+    { _srItems            = mempty
+    , _srCount            = Nothing
+    , _srScannedCount     = Nothing
+    , _srLastEvaluatedKey = mempty
+    , _srConsumedCapacity = Nothing
+    }
+
+srConsumedCapacity :: Lens' ScanResponse (Maybe ConsumedCapacity)
+srConsumedCapacity =
+    lens _srConsumedCapacity (\s a -> s { _srConsumedCapacity = a })
+
+-- | The number of items in the response. If you set ScanFilter in the
+-- request, then Count is the number of items returned after the filter was
+-- applied, and ScannedCount is the number of matching items before the
+-- filter was applied. If you did not use a filter in the request, then
+-- Count is the same as ScannedCount.
+srCount :: Lens' ScanResponse (Maybe Int)
+srCount = lens _srCount (\s a -> s { _srCount = a })
+
+-- | An array of item attributes that match the scan criteria. Each element in
+-- this array consists of an attribute name and the value for that
+-- attribute.
+srItems :: Lens' ScanResponse [HashMap Text AttributeValue]
+srItems = lens _srItems (\s a -> s { _srItems = a }) . _List
+
+-- | The primary key of the item where the operation stopped, inclusive of the
+-- previous result set. Use this value to start a new operation, excluding
+-- this value in the new request. If LastEvaluatedKey is empty, then the
+-- "last page" of results has been processed and there is no more data to be
+-- retrieved. If LastEvaluatedKey is not empty, it does not necessarily mean
+-- that there is more data in the result set. The only way to know when you
+-- have reached the end of the result set is when LastEvaluatedKey is empty.
+srLastEvaluatedKey :: Lens' ScanResponse (HashMap Text AttributeValue)
+srLastEvaluatedKey =
+    lens _srLastEvaluatedKey (\s a -> s { _srLastEvaluatedKey = a })
+        . _Map
+
+-- | The number of items evaluated, before any ScanFilter is applied. A high
+-- ScannedCount value with few, or no, Count results indicates an
+-- inefficient Scan operation. For more information, see Count and
+-- ScannedCount in the Amazon DynamoDB Developer Guide. If you did not use a
+-- filter in the request, then ScannedCount is the same as Count.
+srScannedCount :: Lens' ScanResponse (Maybe Int)
+srScannedCount = lens _srScannedCount (\s a -> s { _srScannedCount = a })
+
+instance ToPath Scan where
+    toPath = const "/"
+
+instance ToQuery Scan where
+    toQuery = const mempty
+
+instance ToHeaders Scan
+
+instance ToJSON Scan where
+    toJSON Scan{..} = object
+        [ "TableName"                 .= _sTableName
+        , "AttributesToGet"           .= _sAttributesToGet
+        , "Limit"                     .= _sLimit
+        , "Select"                    .= _sSelect
+        , "ScanFilter"                .= _sScanFilter
+        , "ConditionalOperator"       .= _sConditionalOperator
+        , "ExclusiveStartKey"         .= _sExclusiveStartKey
+        , "ReturnConsumedCapacity"    .= _sReturnConsumedCapacity
+        , "TotalSegments"             .= _sTotalSegments
+        , "Segment"                   .= _sSegment
+        , "ProjectionExpression"      .= _sProjectionExpression
+        , "FilterExpression"          .= _sFilterExpression
+        , "ExpressionAttributeNames"  .= _sExpressionAttributeNames
+        , "ExpressionAttributeValues" .= _sExpressionAttributeValues
+        ]
+
+instance AWSRequest Scan where
+    type Sv Scan = DynamoDB
+    type Rs Scan = ScanResponse
+
+    request  = post "Scan"
+    response = jsonResponse
+
+instance FromJSON ScanResponse where
+    parseJSON = withObject "ScanResponse" $ \o -> ScanResponse
+        <$> o .:? "ConsumedCapacity"
+        <*> o .:? "Count"
+        <*> o .:  "Items"
+        <*> o .:  "LastEvaluatedKey"
+        <*> o .:? "ScannedCount"
+
+instance AWSPager Scan where
+    page rq rs
+        | stop (rq ^. sExclusiveStartKey) = Nothing
+        | otherwise = Just $ rq
+            & sExclusiveStartKey .~ rs ^. srLastEvaluatedKey
diff --git a/gen/Network/AWS/DynamoDB/Types.hs b/gen/Network/AWS/DynamoDB/Types.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/Types.hs
@@ -0,0 +1,2261 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.Types
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+module Network.AWS.DynamoDB.Types
+    (
+    -- * Service
+      DynamoDB
+    -- ** Error
+    , JSONError
+
+    -- * WriteRequest
+    , WriteRequest
+    , writeRequest
+    , wDeleteRequest
+    , wPutRequest
+
+    -- * ProvisionedThroughputDescription
+    , ProvisionedThroughputDescription
+    , provisionedThroughputDescription
+    , ptdLastDecreaseDateTime
+    , ptdLastIncreaseDateTime
+    , ptdNumberOfDecreasesToday
+    , ptdReadCapacityUnits
+    , ptdWriteCapacityUnits
+
+    -- * KeyType
+    , KeyType (..)
+
+    -- * AttributeValue
+    , AttributeValue
+    , attributeValue
+    , avB
+    , avBOOL
+    , avBS
+    , avL
+    , avM
+    , avN
+    , avNS
+    , avNULL
+    , avS
+    , avSS
+
+    -- * IndexStatus
+    , IndexStatus (..)
+
+    -- * ProvisionedThroughput
+    , ProvisionedThroughput
+    , provisionedThroughput
+    , ptReadCapacityUnits
+    , ptWriteCapacityUnits
+
+    -- * TableStatus
+    , TableStatus (..)
+
+    -- * ProjectionType
+    , ProjectionType (..)
+
+    -- * TableDescription
+    , TableDescription
+    , tableDescription
+    , tdAttributeDefinitions
+    , tdCreationDateTime
+    , tdGlobalSecondaryIndexes
+    , tdItemCount
+    , tdKeySchema
+    , tdLocalSecondaryIndexes
+    , tdProvisionedThroughput
+    , tdTableName
+    , tdTableSizeBytes
+    , tdTableStatus
+
+    -- * KeysAndAttributes
+    , KeysAndAttributes
+    , keysAndAttributes
+    , kaaAttributesToGet
+    , kaaConsistentRead
+    , kaaExpressionAttributeNames
+    , kaaKeys
+    , kaaProjectionExpression
+
+    -- * ReturnConsumedCapacity
+    , ReturnConsumedCapacity (..)
+
+    -- * ReturnItemCollectionMetrics
+    , ReturnItemCollectionMetrics (..)
+
+    -- * AttributeValueUpdate
+    , AttributeValueUpdate
+    , attributeValueUpdate
+    , avuAction
+    , avuValue
+
+    -- * ExpectedAttributeValue
+    , ExpectedAttributeValue
+    , expectedAttributeValue
+    , eavAttributeValueList
+    , eavComparisonOperator
+    , eavExists
+    , eavValue
+
+    -- * AttributeDefinition
+    , AttributeDefinition
+    , attributeDefinition
+    , adAttributeName
+    , adAttributeType
+
+    -- * ComparisonOperator
+    , ComparisonOperator (..)
+
+    -- * ReturnValue
+    , ReturnValue (..)
+
+    -- * LocalSecondaryIndex
+    , LocalSecondaryIndex
+    , localSecondaryIndex
+    , lsiIndexName
+    , lsiKeySchema
+    , lsiProjection
+
+    -- * GlobalSecondaryIndexDescription
+    , GlobalSecondaryIndexDescription
+    , globalSecondaryIndexDescription
+    , gsidIndexName
+    , gsidIndexSizeBytes
+    , gsidIndexStatus
+    , gsidItemCount
+    , gsidKeySchema
+    , gsidProjection
+    , gsidProvisionedThroughput
+
+    -- * ItemCollectionMetrics
+    , ItemCollectionMetrics
+    , itemCollectionMetrics
+    , icmItemCollectionKey
+    , icmSizeEstimateRangeGB
+
+    -- * Capacity
+    , Capacity
+    , capacity
+    , cCapacityUnits
+
+    -- * ConsumedCapacity
+    , ConsumedCapacity
+    , consumedCapacity
+    , ccCapacityUnits
+    , ccGlobalSecondaryIndexes
+    , ccLocalSecondaryIndexes
+    , ccTable
+    , ccTableName
+
+    -- * GlobalSecondaryIndex
+    , GlobalSecondaryIndex
+    , globalSecondaryIndex
+    , gsiIndexName
+    , gsiKeySchema
+    , gsiProjection
+    , gsiProvisionedThroughput
+
+    -- * LocalSecondaryIndexDescription
+    , LocalSecondaryIndexDescription
+    , localSecondaryIndexDescription
+    , lsidIndexName
+    , lsidIndexSizeBytes
+    , lsidItemCount
+    , lsidKeySchema
+    , lsidProjection
+
+    -- * AttributeAction
+    , AttributeAction (..)
+
+    -- * ScalarAttributeType
+    , ScalarAttributeType (..)
+
+    -- * Projection
+    , Projection
+    , projection
+    , pNonKeyAttributes
+    , pProjectionType
+
+    -- * Select
+    , Select (..)
+
+    -- * KeySchemaElement
+    , KeySchemaElement
+    , keySchemaElement
+    , kseAttributeName
+    , kseKeyType
+
+    -- * DeleteRequest
+    , DeleteRequest
+    , deleteRequest
+    , dKey
+
+    -- * UpdateGlobalSecondaryIndexAction
+    , UpdateGlobalSecondaryIndexAction
+    , updateGlobalSecondaryIndexAction
+    , ugsiaIndexName
+    , ugsiaProvisionedThroughput
+
+    -- * PutRequest
+    , PutRequest
+    , putRequest
+    , pItem
+
+    -- * Condition
+    , Condition
+    , condition
+    , cAttributeValueList
+    , cComparisonOperator
+
+    -- * ConditionalOperator
+    , ConditionalOperator (..)
+
+    -- * GlobalSecondaryIndexUpdate
+    , GlobalSecondaryIndexUpdate
+    , globalSecondaryIndexUpdate
+    , gsiuUpdate
+    ) where
+
+import Data.Char (isUpper)
+import Network.AWS.Error
+import Network.AWS.Prelude
+import Network.AWS.Signing.V4
+import qualified GHC.Exts
+
+-- | Version @2012-08-10@ of the Amazon DynamoDB service.
+data DynamoDB
+
+instance AWSService DynamoDB where
+    type Sg DynamoDB = V4
+    type Er DynamoDB = JSONError
+
+    service = Service
+        { _svcEndpoint     = regional
+        , _svcAbbrev       = "DynamoDB"
+        , _svcPrefix       = "dynamodb"
+        , _svcVersion      = "2012-08-10"
+        , _svcTargetPrefix = Just "DynamoDB_20120810"
+        , _svcJSONVersion  = Just "1.0"
+        }
+
+    handle = jsonError statusSuccess
+
+data WriteRequest = WriteRequest
+    { _wDeleteRequest :: Maybe DeleteRequest
+    , _wPutRequest    :: Maybe PutRequest
+    } deriving (Eq, Show)
+
+-- | 'WriteRequest' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'wDeleteRequest' @::@ 'Maybe' 'DeleteRequest'
+--
+-- * 'wPutRequest' @::@ 'Maybe' 'PutRequest'
+--
+writeRequest :: WriteRequest
+writeRequest = WriteRequest
+    { _wPutRequest    = Nothing
+    , _wDeleteRequest = Nothing
+    }
+
+-- | A request to perform a DeleteItem operation.
+wDeleteRequest :: Lens' WriteRequest (Maybe DeleteRequest)
+wDeleteRequest = lens _wDeleteRequest (\s a -> s { _wDeleteRequest = a })
+
+-- | A request to perform a PutItem operation.
+wPutRequest :: Lens' WriteRequest (Maybe PutRequest)
+wPutRequest = lens _wPutRequest (\s a -> s { _wPutRequest = a })
+
+instance FromJSON WriteRequest where
+    parseJSON = withObject "WriteRequest" $ \o -> WriteRequest
+        <$> o .:? "DeleteRequest"
+        <*> o .:? "PutRequest"
+
+instance ToJSON WriteRequest where
+    toJSON WriteRequest{..} = object
+        [ "PutRequest"    .= _wPutRequest
+        , "DeleteRequest" .= _wDeleteRequest
+        ]
+
+data ProvisionedThroughputDescription = ProvisionedThroughputDescription
+    { _ptdLastDecreaseDateTime   :: Maybe RFC822
+    , _ptdLastIncreaseDateTime   :: Maybe RFC822
+    , _ptdNumberOfDecreasesToday :: Maybe Nat
+    , _ptdReadCapacityUnits      :: Maybe Nat
+    , _ptdWriteCapacityUnits     :: Maybe Nat
+    } deriving (Eq, Ord, Show)
+
+-- | 'ProvisionedThroughputDescription' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'ptdLastDecreaseDateTime' @::@ 'Maybe' 'UTCTime'
+--
+-- * 'ptdLastIncreaseDateTime' @::@ 'Maybe' 'UTCTime'
+--
+-- * 'ptdNumberOfDecreasesToday' @::@ 'Maybe' 'Natural'
+--
+-- * 'ptdReadCapacityUnits' @::@ 'Maybe' 'Natural'
+--
+-- * 'ptdWriteCapacityUnits' @::@ 'Maybe' 'Natural'
+--
+provisionedThroughputDescription :: ProvisionedThroughputDescription
+provisionedThroughputDescription = ProvisionedThroughputDescription
+    { _ptdLastIncreaseDateTime   = Nothing
+    , _ptdLastDecreaseDateTime   = Nothing
+    , _ptdNumberOfDecreasesToday = Nothing
+    , _ptdReadCapacityUnits      = Nothing
+    , _ptdWriteCapacityUnits     = Nothing
+    }
+
+-- | The date and time of the last provisioned throughput decrease for this
+-- table.
+ptdLastDecreaseDateTime :: Lens' ProvisionedThroughputDescription (Maybe UTCTime)
+ptdLastDecreaseDateTime =
+    lens _ptdLastDecreaseDateTime (\s a -> s { _ptdLastDecreaseDateTime = a })
+        . mapping _Time
+
+-- | The date and time of the last provisioned throughput increase for this
+-- table.
+ptdLastIncreaseDateTime :: Lens' ProvisionedThroughputDescription (Maybe UTCTime)
+ptdLastIncreaseDateTime =
+    lens _ptdLastIncreaseDateTime (\s a -> s { _ptdLastIncreaseDateTime = a })
+        . mapping _Time
+
+-- | The number of provisioned throughput decreases for this table during this
+-- UTC calendar day. For current maximums on provisioned throughput
+-- decreases, see Limits in the Amazon DynamoDB Developer Guide.
+ptdNumberOfDecreasesToday :: Lens' ProvisionedThroughputDescription (Maybe Natural)
+ptdNumberOfDecreasesToday =
+    lens _ptdNumberOfDecreasesToday
+        (\s a -> s { _ptdNumberOfDecreasesToday = a })
+            . mapping _Nat
+
+-- | The maximum number of strongly consistent reads consumed per second
+-- before DynamoDB returns a ThrottlingException. Eventually consistent
+-- reads require less effort than strongly consistent reads, so a setting of
+-- 50 ReadCapacityUnits per second provides 100 eventually consistent
+-- ReadCapacityUnits per second.
+ptdReadCapacityUnits :: Lens' ProvisionedThroughputDescription (Maybe Natural)
+ptdReadCapacityUnits =
+    lens _ptdReadCapacityUnits (\s a -> s { _ptdReadCapacityUnits = a })
+        . mapping _Nat
+
+-- | The maximum number of writes consumed per second before DynamoDB returns
+-- a ThrottlingException.
+ptdWriteCapacityUnits :: Lens' ProvisionedThroughputDescription (Maybe Natural)
+ptdWriteCapacityUnits =
+    lens _ptdWriteCapacityUnits (\s a -> s { _ptdWriteCapacityUnits = a })
+        . mapping _Nat
+
+instance FromJSON ProvisionedThroughputDescription where
+    parseJSON = withObject "ProvisionedThroughputDescription" $ \o -> ProvisionedThroughputDescription
+        <$> o .:? "LastDecreaseDateTime"
+        <*> o .:? "LastIncreaseDateTime"
+        <*> o .:? "NumberOfDecreasesToday"
+        <*> o .:? "ReadCapacityUnits"
+        <*> o .:? "WriteCapacityUnits"
+
+instance ToJSON ProvisionedThroughputDescription where
+    toJSON ProvisionedThroughputDescription{..} = object
+        [ "LastIncreaseDateTime"   .= _ptdLastIncreaseDateTime
+        , "LastDecreaseDateTime"   .= _ptdLastDecreaseDateTime
+        , "NumberOfDecreasesToday" .= _ptdNumberOfDecreasesToday
+        , "ReadCapacityUnits"      .= _ptdReadCapacityUnits
+        , "WriteCapacityUnits"     .= _ptdWriteCapacityUnits
+        ]
+
+data KeyType
+    = Hash  -- ^ HASH
+    | Range -- ^ RANGE
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable KeyType
+
+instance FromText KeyType where
+    parser = match "HASH"  Hash
+         <|> match "RANGE" Range
+
+instance ToText KeyType where
+    toText = \case
+        Hash  -> "HASH"
+        Range -> "RANGE"
+
+instance FromJSON KeyType where
+    parseJSON = parseJSONText "KeyType"
+
+instance ToJSON KeyType where
+    toJSON = toJSONText
+
+data AttributeValue = AttributeValue
+    { _avB    :: Maybe Base64
+    , _avBOOL :: Maybe Bool
+    , _avBS   :: List "BS" Base64
+    , _avL    :: List "L" AttributeValue
+    , _avM    :: Map Text AttributeValue
+    , _avN    :: Maybe Text
+    , _avNS   :: List "NS" Text
+    , _avNULL :: Maybe Bool
+    , _avS    :: Maybe Text
+    , _avSS   :: List "SS" Text
+    } deriving (Eq, Show)
+
+-- | 'AttributeValue' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'avB' @::@ 'Maybe' 'Base64'
+--
+-- * 'avBOOL' @::@ 'Maybe' 'Bool'
+--
+-- * 'avBS' @::@ ['Base64']
+--
+-- * 'avL' @::@ ['AttributeValue']
+--
+-- * 'avM' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'avN' @::@ 'Maybe' 'Text'
+--
+-- * 'avNS' @::@ ['Text']
+--
+-- * 'avNULL' @::@ 'Maybe' 'Bool'
+--
+-- * 'avS' @::@ 'Maybe' 'Text'
+--
+-- * 'avSS' @::@ ['Text']
+--
+attributeValue :: AttributeValue
+attributeValue = AttributeValue
+    { _avS    = Nothing
+    , _avN    = Nothing
+    , _avB    = Nothing
+    , _avSS   = mempty
+    , _avNS   = mempty
+    , _avBS   = mempty
+    , _avM    = mempty
+    , _avL    = mempty
+    , _avNULL = Nothing
+    , _avBOOL = Nothing
+    }
+
+-- | A Binary data type.
+avB :: Lens' AttributeValue (Maybe Base64)
+avB = lens _avB (\s a -> s { _avB = a })
+
+-- | A Boolean data type.
+avBOOL :: Lens' AttributeValue (Maybe Bool)
+avBOOL = lens _avBOOL (\s a -> s { _avBOOL = a })
+
+-- | A Binary Set data type.
+avBS :: Lens' AttributeValue [Base64]
+avBS = lens _avBS (\s a -> s { _avBS = a }) . _List
+
+-- | A List of attribute values.
+avL :: Lens' AttributeValue [AttributeValue]
+avL = lens _avL (\s a -> s { _avL = a }) . _List
+
+-- | A Map of attribute values.
+avM :: Lens' AttributeValue (HashMap Text AttributeValue)
+avM = lens _avM (\s a -> s { _avM = a }) . _Map
+
+-- | A Number data type.
+avN :: Lens' AttributeValue (Maybe Text)
+avN = lens _avN (\s a -> s { _avN = a })
+
+-- | A Number Set data type.
+avNS :: Lens' AttributeValue [Text]
+avNS = lens _avNS (\s a -> s { _avNS = a }) . _List
+
+-- | A Null data type.
+avNULL :: Lens' AttributeValue (Maybe Bool)
+avNULL = lens _avNULL (\s a -> s { _avNULL = a })
+
+-- | A String data type.
+avS :: Lens' AttributeValue (Maybe Text)
+avS = lens _avS (\s a -> s { _avS = a })
+
+-- | A String Set data type.
+avSS :: Lens' AttributeValue [Text]
+avSS = lens _avSS (\s a -> s { _avSS = a }) . _List
+
+instance FromJSON AttributeValue where
+    parseJSON = withObject "AttributeValue" $ \o -> AttributeValue
+        <$> o .:? "B"
+        <*> o .:? "BOOL"
+        <*> o .:  "BS"
+        <*> o .:  "L"
+        <*> o .:  "M"
+        <*> o .:? "N"
+        <*> o .:  "NS"
+        <*> o .:? "NULL"
+        <*> o .:? "S"
+        <*> o .:  "SS"
+
+instance ToJSON AttributeValue where
+    toJSON AttributeValue{..} = object
+        [ "S"    .= _avS
+        , "N"    .= _avN
+        , "B"    .= _avB
+        , "SS"   .= _avSS
+        , "NS"   .= _avNS
+        , "BS"   .= _avBS
+        , "M"    .= _avM
+        , "L"    .= _avL
+        , "NULL" .= _avNULL
+        , "BOOL" .= _avBOOL
+        ]
+
+data IndexStatus
+    = Active   -- ^ ACTIVE
+    | Creating -- ^ CREATING
+    | Deleting -- ^ DELETING
+    | Updating -- ^ UPDATING
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable IndexStatus
+
+instance FromText IndexStatus where
+    parser = match "ACTIVE"   Active
+         <|> match "CREATING" Creating
+         <|> match "DELETING" Deleting
+         <|> match "UPDATING" Updating
+
+instance ToText IndexStatus where
+    toText = \case
+        Active   -> "ACTIVE"
+        Creating -> "CREATING"
+        Deleting -> "DELETING"
+        Updating -> "UPDATING"
+
+instance FromJSON IndexStatus where
+    parseJSON = parseJSONText "IndexStatus"
+
+instance ToJSON IndexStatus where
+    toJSON = toJSONText
+
+data ProvisionedThroughput = ProvisionedThroughput
+    { _ptReadCapacityUnits  :: Nat
+    , _ptWriteCapacityUnits :: Nat
+    } deriving (Eq, Ord, Show)
+
+-- | 'ProvisionedThroughput' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'ptReadCapacityUnits' @::@ 'Natural'
+--
+-- * 'ptWriteCapacityUnits' @::@ 'Natural'
+--
+provisionedThroughput :: Natural -- ^ 'ptReadCapacityUnits'
+                      -> Natural -- ^ 'ptWriteCapacityUnits'
+                      -> ProvisionedThroughput
+provisionedThroughput p1 p2 = ProvisionedThroughput
+    { _ptReadCapacityUnits  = withIso _Nat (const id) p1
+    , _ptWriteCapacityUnits = withIso _Nat (const id) p2
+    }
+
+-- | The maximum number of strongly consistent reads consumed per second
+-- before DynamoDB returns a ThrottlingException. For more information, see
+-- Specifying Read and Write Requirements in the Amazon DynamoDB Developer
+-- Guide.
+ptReadCapacityUnits :: Lens' ProvisionedThroughput Natural
+ptReadCapacityUnits =
+    lens _ptReadCapacityUnits (\s a -> s { _ptReadCapacityUnits = a })
+        . _Nat
+
+-- | The maximum number of writes consumed per second before DynamoDB returns
+-- a ThrottlingException. For more information, see Specifying Read and
+-- Write Requirements in the Amazon DynamoDB Developer Guide.
+ptWriteCapacityUnits :: Lens' ProvisionedThroughput Natural
+ptWriteCapacityUnits =
+    lens _ptWriteCapacityUnits (\s a -> s { _ptWriteCapacityUnits = a })
+        . _Nat
+
+instance FromJSON ProvisionedThroughput where
+    parseJSON = withObject "ProvisionedThroughput" $ \o -> ProvisionedThroughput
+        <$> o .:  "ReadCapacityUnits"
+        <*> o .:  "WriteCapacityUnits"
+
+instance ToJSON ProvisionedThroughput where
+    toJSON ProvisionedThroughput{..} = object
+        [ "ReadCapacityUnits"  .= _ptReadCapacityUnits
+        , "WriteCapacityUnits" .= _ptWriteCapacityUnits
+        ]
+
+data TableStatus
+    = TSActive   -- ^ ACTIVE
+    | TSCreating -- ^ CREATING
+    | TSDeleting -- ^ DELETING
+    | TSUpdating -- ^ UPDATING
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable TableStatus
+
+instance FromText TableStatus where
+    parser = match "ACTIVE"   TSActive
+         <|> match "CREATING" TSCreating
+         <|> match "DELETING" TSDeleting
+         <|> match "UPDATING" TSUpdating
+
+instance ToText TableStatus where
+    toText = \case
+        TSActive   -> "ACTIVE"
+        TSCreating -> "CREATING"
+        TSDeleting -> "DELETING"
+        TSUpdating -> "UPDATING"
+
+instance FromJSON TableStatus where
+    parseJSON = parseJSONText "TableStatus"
+
+instance ToJSON TableStatus where
+    toJSON = toJSONText
+
+data ProjectionType
+    = All      -- ^ ALL
+    | Include  -- ^ INCLUDE
+    | KeysOnly -- ^ KEYS_ONLY
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable ProjectionType
+
+instance FromText ProjectionType where
+    parser = match "ALL"       All
+         <|> match "INCLUDE"   Include
+         <|> match "KEYS_ONLY" KeysOnly
+
+instance ToText ProjectionType where
+    toText = \case
+        All      -> "ALL"
+        Include  -> "INCLUDE"
+        KeysOnly -> "KEYS_ONLY"
+
+instance FromJSON ProjectionType where
+    parseJSON = parseJSONText "ProjectionType"
+
+instance ToJSON ProjectionType where
+    toJSON = toJSONText
+
+data TableDescription = TableDescription
+    { _tdAttributeDefinitions   :: List "AttributeDefinitions" AttributeDefinition
+    , _tdCreationDateTime       :: Maybe RFC822
+    , _tdGlobalSecondaryIndexes :: List "GlobalSecondaryIndexes" GlobalSecondaryIndexDescription
+    , _tdItemCount              :: Maybe Integer
+    , _tdKeySchema              :: List1 "KeySchema" KeySchemaElement
+    , _tdLocalSecondaryIndexes  :: List "LocalSecondaryIndexes" LocalSecondaryIndexDescription
+    , _tdProvisionedThroughput  :: Maybe ProvisionedThroughputDescription
+    , _tdTableName              :: Maybe Text
+    , _tdTableSizeBytes         :: Maybe Integer
+    , _tdTableStatus            :: Maybe Text
+    } deriving (Eq, Show)
+
+-- | 'TableDescription' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'tdAttributeDefinitions' @::@ ['AttributeDefinition']
+--
+-- * 'tdCreationDateTime' @::@ 'Maybe' 'UTCTime'
+--
+-- * 'tdGlobalSecondaryIndexes' @::@ ['GlobalSecondaryIndexDescription']
+--
+-- * 'tdItemCount' @::@ 'Maybe' 'Integer'
+--
+-- * 'tdKeySchema' @::@ 'NonEmpty' 'KeySchemaElement'
+--
+-- * 'tdLocalSecondaryIndexes' @::@ ['LocalSecondaryIndexDescription']
+--
+-- * 'tdProvisionedThroughput' @::@ 'Maybe' 'ProvisionedThroughputDescription'
+--
+-- * 'tdTableName' @::@ 'Maybe' 'Text'
+--
+-- * 'tdTableSizeBytes' @::@ 'Maybe' 'Integer'
+--
+-- * 'tdTableStatus' @::@ 'Maybe' 'Text'
+--
+tableDescription :: NonEmpty KeySchemaElement -- ^ 'tdKeySchema'
+                 -> TableDescription
+tableDescription p1 = TableDescription
+    { _tdKeySchema              = withIso _List1 (const id) p1
+    , _tdAttributeDefinitions   = mempty
+    , _tdTableName              = Nothing
+    , _tdTableStatus            = Nothing
+    , _tdCreationDateTime       = Nothing
+    , _tdProvisionedThroughput  = Nothing
+    , _tdTableSizeBytes         = Nothing
+    , _tdItemCount              = Nothing
+    , _tdLocalSecondaryIndexes  = mempty
+    , _tdGlobalSecondaryIndexes = mempty
+    }
+
+-- | An array of AttributeDefinition objects. Each of these objects describes
+-- one attribute in the table and index key schema. Each AttributeDefinition
+-- object in this array is composed of: AttributeName - The name of the
+-- attribute. AttributeType - The data type for the attribute.
+tdAttributeDefinitions :: Lens' TableDescription [AttributeDefinition]
+tdAttributeDefinitions =
+    lens _tdAttributeDefinitions (\s a -> s { _tdAttributeDefinitions = a })
+        . _List
+
+-- | The date and time when the table was created, in UNIX epoch time format.
+tdCreationDateTime :: Lens' TableDescription (Maybe UTCTime)
+tdCreationDateTime =
+    lens _tdCreationDateTime (\s a -> s { _tdCreationDateTime = a })
+        . mapping _Time
+
+-- | The global secondary indexes, if any, on the table. Each index is scoped
+-- to a given hash key value. Each element is composed of: IndexName - The
+-- name of the global secondary index. IndexSizeBytes - The total size of
+-- the global secondary index, in bytes. DynamoDB updates this value
+-- approximately every six hours. Recent changes might not be reflected in
+-- this value. IndexStatus - The current status of the global secondary
+-- index: CREATING - The index is being created. UPDATING - The index is
+-- being updated. DELETING - The index is being deleted. ACTIVE - The index
+-- is ready for use. ItemCount - The number of items in the global secondary
+-- index. DynamoDB updates this value approximately every six hours. Recent
+-- changes might not be reflected in this value. KeySchema - Specifies the
+-- complete index key schema. The attribute names in the key schema must be
+-- between 1 and 255 characters (inclusive). The key schema must begin with
+-- the same hash key attribute as the table. Projection - Specifies
+-- attributes that are copied (projected) from the table into the index.
+-- These are in addition to the primary key attributes and index key
+-- attributes, which are automatically projected. Each attribute
+-- specification is composed of: ProjectionType - One of the following:
+-- KEYS_ONLY - Only the index and primary keys are projected into the index.
+-- INCLUDE - Only the specified table attributes are projected into the
+-- index. The list of projected attributes are in NonKeyAttributes. ALL -
+-- All of the table attributes are projected into the index.
+-- NonKeyAttributes - A list of one or more non-key attribute names that are
+-- projected into the secondary index. The total count of attributes
+-- specified in NonKeyAttributes, summed across all of the secondary
+-- indexes, must not exceed 20. If you project the same attribute into two
+-- different indexes, this counts as two distinct attributes when
+-- determining the total. ProvisionedThroughput - The provisioned throughput
+-- settings for the global secondary index, consisting of read and write
+-- capacity units, along with data about increases and decreases. If the
+-- table is in the DELETING state, no information about indexes will be
+-- returned.
+tdGlobalSecondaryIndexes :: Lens' TableDescription [GlobalSecondaryIndexDescription]
+tdGlobalSecondaryIndexes =
+    lens _tdGlobalSecondaryIndexes
+        (\s a -> s { _tdGlobalSecondaryIndexes = a })
+            . _List
+
+-- | The number of items in the specified table. DynamoDB updates this value
+-- approximately every six hours. Recent changes might not be reflected in
+-- this value.
+tdItemCount :: Lens' TableDescription (Maybe Integer)
+tdItemCount = lens _tdItemCount (\s a -> s { _tdItemCount = a })
+
+-- | The primary key structure for the table. Each KeySchemaElement consists
+-- of: AttributeName - The name of the attribute. KeyType - The key type for
+-- the attribute. Can be either HASH or RANGE. For more information about
+-- primary keys, see Primary Key in the Amazon DynamoDB Developer Guide.
+tdKeySchema :: Lens' TableDescription (NonEmpty KeySchemaElement)
+tdKeySchema = lens _tdKeySchema (\s a -> s { _tdKeySchema = a }) . _List1
+
+-- | Represents one or more local secondary indexes on the table. Each index
+-- is scoped to a given hash key value. Tables with one or more local
+-- secondary indexes are subject to an item collection size limit, where the
+-- amount of data within a given item collection cannot exceed 10 GB. Each
+-- element is composed of: IndexName - The name of the local secondary
+-- index. KeySchema - Specifies the complete index key schema. The attribute
+-- names in the key schema must be between 1 and 255 characters (inclusive).
+-- The key schema must begin with the same hash key attribute as the table.
+-- Projection - Specifies attributes that are copied (projected) from the
+-- table into the index. These are in addition to the primary key attributes
+-- and index key attributes, which are automatically projected. Each
+-- attribute specification is composed of: ProjectionType - One of the
+-- following: KEYS_ONLY - Only the index and primary keys are projected into
+-- the index. INCLUDE - Only the specified table attributes are projected
+-- into the index. The list of projected attributes are in NonKeyAttributes.
+-- ALL - All of the table attributes are projected into the index.
+-- NonKeyAttributes - A list of one or more non-key attribute names that are
+-- projected into the secondary index. The total count of attributes
+-- specified in NonKeyAttributes, summed across all of the secondary
+-- indexes, must not exceed 20. If you project the same attribute into two
+-- different indexes, this counts as two distinct attributes when
+-- determining the total. IndexSizeBytes - Represents the total size of the
+-- index, in bytes. DynamoDB updates this value approximately every six
+-- hours. Recent changes might not be reflected in this value. ItemCount -
+-- Represents the number of items in the index. DynamoDB updates this value
+-- approximately every six hours. Recent changes might not be reflected in
+-- this value. If the table is in the DELETING state, no information about
+-- indexes will be returned.
+tdLocalSecondaryIndexes :: Lens' TableDescription [LocalSecondaryIndexDescription]
+tdLocalSecondaryIndexes =
+    lens _tdLocalSecondaryIndexes (\s a -> s { _tdLocalSecondaryIndexes = a })
+        . _List
+
+-- | The provisioned throughput settings for the table, consisting of read and
+-- write capacity units, along with data about increases and decreases.
+tdProvisionedThroughput :: Lens' TableDescription (Maybe ProvisionedThroughputDescription)
+tdProvisionedThroughput =
+    lens _tdProvisionedThroughput (\s a -> s { _tdProvisionedThroughput = a })
+
+-- | The name of the table.
+tdTableName :: Lens' TableDescription (Maybe Text)
+tdTableName = lens _tdTableName (\s a -> s { _tdTableName = a })
+
+-- | The total size of the specified table, in bytes. DynamoDB updates this
+-- value approximately every six hours. Recent changes might not be
+-- reflected in this value.
+tdTableSizeBytes :: Lens' TableDescription (Maybe Integer)
+tdTableSizeBytes = lens _tdTableSizeBytes (\s a -> s { _tdTableSizeBytes = a })
+
+-- | The current state of the table: CREATING - The table is being created, as
+-- the result of a CreateTable operation. UPDATING - The table is being
+-- updated, as the result of an UpdateTable operation. DELETING - The table
+-- is being deleted, as the result of a DeleteTable operation. ACTIVE - The
+-- table is ready for use.
+tdTableStatus :: Lens' TableDescription (Maybe Text)
+tdTableStatus = lens _tdTableStatus (\s a -> s { _tdTableStatus = a })
+
+instance FromJSON TableDescription where
+    parseJSON = withObject "TableDescription" $ \o -> TableDescription
+        <$> o .:  "AttributeDefinitions"
+        <*> o .:? "CreationDateTime"
+        <*> o .:  "GlobalSecondaryIndexes"
+        <*> o .:? "ItemCount"
+        <*> o .:  "KeySchema"
+        <*> o .:  "LocalSecondaryIndexes"
+        <*> o .:? "ProvisionedThroughput"
+        <*> o .:? "TableName"
+        <*> o .:? "TableSizeBytes"
+        <*> o .:? "TableStatus"
+
+instance ToJSON TableDescription where
+    toJSON TableDescription{..} = object
+        [ "AttributeDefinitions"   .= _tdAttributeDefinitions
+        , "TableName"              .= _tdTableName
+        , "KeySchema"              .= _tdKeySchema
+        , "TableStatus"            .= _tdTableStatus
+        , "CreationDateTime"       .= _tdCreationDateTime
+        , "ProvisionedThroughput"  .= _tdProvisionedThroughput
+        , "TableSizeBytes"         .= _tdTableSizeBytes
+        , "ItemCount"              .= _tdItemCount
+        , "LocalSecondaryIndexes"  .= _tdLocalSecondaryIndexes
+        , "GlobalSecondaryIndexes" .= _tdGlobalSecondaryIndexes
+        ]
+
+data KeysAndAttributes = KeysAndAttributes
+    { _kaaAttributesToGet          :: List1 "AttributesToGet" Text
+    , _kaaConsistentRead           :: Maybe Bool
+    , _kaaExpressionAttributeNames :: Map Text Text
+    , _kaaKeys                     :: List1 "Keys" (Map Text AttributeValue)
+    , _kaaProjectionExpression     :: Maybe Text
+    } deriving (Eq, Show)
+
+-- | 'KeysAndAttributes' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'kaaAttributesToGet' @::@ 'NonEmpty' 'Text'
+--
+-- * 'kaaConsistentRead' @::@ 'Maybe' 'Bool'
+--
+-- * 'kaaExpressionAttributeNames' @::@ 'HashMap' 'Text' 'Text'
+--
+-- * 'kaaKeys' @::@ 'NonEmpty' ('HashMap' 'Text' 'AttributeValue')
+--
+-- * 'kaaProjectionExpression' @::@ 'Maybe' 'Text'
+--
+keysAndAttributes :: NonEmpty (HashMap Text AttributeValue) -- ^ 'kaaKeys'
+                  -> NonEmpty Text -- ^ 'kaaAttributesToGet'
+                  -> KeysAndAttributes
+keysAndAttributes p1 p2 = KeysAndAttributes
+    { _kaaKeys                     = withIso _List1 (const id) p1
+    , _kaaAttributesToGet          = withIso _List1 (const id) p2
+    , _kaaConsistentRead           = Nothing
+    , _kaaProjectionExpression     = Nothing
+    , _kaaExpressionAttributeNames = mempty
+    }
+
+-- | One or more attributes to retrieve from the table or index. If no
+-- attribute names are specified then all attributes will be returned. If
+-- any of the specified attributes are not found, they will not appear in
+-- the result.
+kaaAttributesToGet :: Lens' KeysAndAttributes (NonEmpty Text)
+kaaAttributesToGet =
+    lens _kaaAttributesToGet (\s a -> s { _kaaAttributesToGet = a })
+        . _List1
+
+-- | The consistency of a read operation. If set to true, then a strongly
+-- consistent read is used; otherwise, an eventually consistent read is
+-- used.
+kaaConsistentRead :: Lens' KeysAndAttributes (Maybe Bool)
+kaaConsistentRead =
+    lens _kaaConsistentRead (\s a -> s { _kaaConsistentRead = a })
+
+-- | One or more substitution tokens for simplifying complex expressions. The
+-- following are some use cases for an ExpressionAttributeNames value: To
+-- shorten an attribute name that is very long or unwieldy in an expression.
+-- To create a placeholder for repeating occurrences of an attribute name in
+-- an expression. To prevent special characters in an attribute name from
+-- being misinterpreted in an expression. Use the # character in an
+-- expression to dereference an attribute name. For example, consider the
+-- following expression: order.customerInfo.LastName = "Smith" OR
+-- order.customerInfo.LastName = "Jones" Now suppose that you specified the
+-- following for ExpressionAttributeNames:
+-- {"n":"order.customerInfo.LastName"} The expression can now be simplified
+-- as follows: #n = "Smith" OR #n = "Jones".
+kaaExpressionAttributeNames :: Lens' KeysAndAttributes (HashMap Text Text)
+kaaExpressionAttributeNames =
+    lens _kaaExpressionAttributeNames
+        (\s a -> s { _kaaExpressionAttributeNames = a })
+            . _Map
+
+-- | The primary key attribute values that define the items and the attributes
+-- associated with the items.
+kaaKeys :: Lens' KeysAndAttributes (NonEmpty (HashMap Text AttributeValue))
+kaaKeys = lens _kaaKeys (\s a -> s { _kaaKeys = a }) . _List1
+
+-- | One or more attributes to retrieve from the table. These attributes can
+-- include scalars, sets, or elements of a JSON document. The attributes in
+-- the expression must be separated by commas. If no attribute names are
+-- specified, then all attributes will be returned. If any of the requested
+-- attributes are not found, they will not appear in the result.
+kaaProjectionExpression :: Lens' KeysAndAttributes (Maybe Text)
+kaaProjectionExpression =
+    lens _kaaProjectionExpression (\s a -> s { _kaaProjectionExpression = a })
+
+instance FromJSON KeysAndAttributes where
+    parseJSON = withObject "KeysAndAttributes" $ \o -> KeysAndAttributes
+        <$> o .:  "AttributesToGet"
+        <*> o .:? "ConsistentRead"
+        <*> o .:  "ExpressionAttributeNames"
+        <*> o .:  "Keys"
+        <*> o .:? "ProjectionExpression"
+
+instance ToJSON KeysAndAttributes where
+    toJSON KeysAndAttributes{..} = object
+        [ "Keys"                     .= _kaaKeys
+        , "AttributesToGet"          .= _kaaAttributesToGet
+        , "ConsistentRead"           .= _kaaConsistentRead
+        , "ProjectionExpression"     .= _kaaProjectionExpression
+        , "ExpressionAttributeNames" .= _kaaExpressionAttributeNames
+        ]
+
+data ReturnConsumedCapacity
+    = Indexes -- ^ INDEXES
+    | None    -- ^ NONE
+    | Total   -- ^ TOTAL
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable ReturnConsumedCapacity
+
+instance FromText ReturnConsumedCapacity where
+    parser = match "INDEXES" Indexes
+         <|> match "NONE"    None
+         <|> match "TOTAL"   Total
+
+instance ToText ReturnConsumedCapacity where
+    toText = \case
+        Indexes -> "INDEXES"
+        None    -> "NONE"
+        Total   -> "TOTAL"
+
+instance FromJSON ReturnConsumedCapacity where
+    parseJSON = parseJSONText "ReturnConsumedCapacity"
+
+instance ToJSON ReturnConsumedCapacity where
+    toJSON = toJSONText
+
+data ReturnItemCollectionMetrics
+    = RICMNone -- ^ NONE
+    | RICMSize -- ^ SIZE
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable ReturnItemCollectionMetrics
+
+instance FromText ReturnItemCollectionMetrics where
+    parser = match "NONE" RICMNone
+         <|> match "SIZE" RICMSize
+
+instance ToText ReturnItemCollectionMetrics where
+    toText = \case
+        RICMNone -> "NONE"
+        RICMSize -> "SIZE"
+
+instance FromJSON ReturnItemCollectionMetrics where
+    parseJSON = parseJSONText "ReturnItemCollectionMetrics"
+
+instance ToJSON ReturnItemCollectionMetrics where
+    toJSON = toJSONText
+
+data AttributeValueUpdate = AttributeValueUpdate
+    { _avuAction :: Maybe Text
+    , _avuValue  :: Maybe AttributeValue
+    } deriving (Eq, Show)
+
+-- | 'AttributeValueUpdate' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'avuAction' @::@ 'Maybe' 'Text'
+--
+-- * 'avuValue' @::@ 'Maybe' 'AttributeValue'
+--
+attributeValueUpdate :: AttributeValueUpdate
+attributeValueUpdate = AttributeValueUpdate
+    { _avuValue  = Nothing
+    , _avuAction = Nothing
+    }
+
+-- | Specifies how to perform the update. Valid values are PUT (default),
+-- DELETE, and ADD. The behavior depends on whether the specified primary
+-- key already exists in the table. If an item with the specified Key is
+-- found in the table: PUT - Adds the specified attribute to the item. If
+-- the attribute already exists, it is replaced by the new value. DELETE -
+-- If no value is specified, the attribute and its value are removed from
+-- the item. The data type of the specified value must match the existing
+-- value's data type. If a set of values is specified, then those values are
+-- subtracted from the old set. For example, if the attribute value was the
+-- set [a,b,c] and the DELETE action specified [a,c], then the final
+-- attribute value would be [b]. Specifying an empty set is an error. ADD -
+-- If the attribute does not already exist, then the attribute and its
+-- values are added to the item. If the attribute does exist, then the
+-- behavior of ADD depends on the data type of the attribute: If the
+-- existing attribute is a number, and if Value is also a number, then the
+-- Value is mathematically added to the existing attribute. If Value is a
+-- negative number, then it is subtracted from the existing attribute. If
+-- the existing data type is a set, and if the Value is also a set, then the
+-- Value is added to the existing set. (This is a set operation, not
+-- mathematical addition.) For example, if the attribute value was the set
+-- [1,2], and the ADD action specified [3], then the final attribute value
+-- would be [1,2,3]. An error occurs if an Add action is specified for a set
+-- attribute and the attribute type specified does not match the existing
+-- set type. Both sets must have the same primitive data type. For example,
+-- if the existing data type is a set of strings, the Value must also be a
+-- set of strings. The same holds true for number sets and binary sets. This
+-- action is only valid for an existing attribute whose data type is number
+-- or is a set. Do not use ADD for any other data types. If no item with the
+-- specified Key is found: PUT - DynamoDB creates a new item with the
+-- specified primary key, and then adds the attribute. DELETE - Nothing
+-- happens; there is no attribute to delete. ADD - DynamoDB creates an item
+-- with the supplied primary key and number (or set of numbers) for the
+-- attribute value. The only data types allowed are number and number set;
+-- no other data types can be specified.
+avuAction :: Lens' AttributeValueUpdate (Maybe Text)
+avuAction = lens _avuAction (\s a -> s { _avuAction = a })
+
+avuValue :: Lens' AttributeValueUpdate (Maybe AttributeValue)
+avuValue = lens _avuValue (\s a -> s { _avuValue = a })
+
+instance FromJSON AttributeValueUpdate where
+    parseJSON = withObject "AttributeValueUpdate" $ \o -> AttributeValueUpdate
+        <$> o .:? "Action"
+        <*> o .:? "Value"
+
+instance ToJSON AttributeValueUpdate where
+    toJSON AttributeValueUpdate{..} = object
+        [ "Value"  .= _avuValue
+        , "Action" .= _avuAction
+        ]
+
+data ExpectedAttributeValue = ExpectedAttributeValue
+    { _eavAttributeValueList :: List "AttributeValueList" AttributeValue
+    , _eavComparisonOperator :: Maybe Text
+    , _eavExists             :: Maybe Bool
+    , _eavValue              :: Maybe AttributeValue
+    } deriving (Eq, Show)
+
+-- | 'ExpectedAttributeValue' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'eavAttributeValueList' @::@ ['AttributeValue']
+--
+-- * 'eavComparisonOperator' @::@ 'Maybe' 'Text'
+--
+-- * 'eavExists' @::@ 'Maybe' 'Bool'
+--
+-- * 'eavValue' @::@ 'Maybe' 'AttributeValue'
+--
+expectedAttributeValue :: ExpectedAttributeValue
+expectedAttributeValue = ExpectedAttributeValue
+    { _eavValue              = Nothing
+    , _eavExists             = Nothing
+    , _eavComparisonOperator = Nothing
+    , _eavAttributeValueList = mempty
+    }
+
+-- | One or more values to evaluate against the supplied attribute. The number
+-- of values in the list depends on the ComparisonOperator being used. For
+-- type Number, value comparisons are numeric. String value comparisons for
+-- greater than, equals, or less than are based on ASCII character code
+-- values. For example, a is greater than A, and aa is greater than B. For a
+-- list of code values, see
+-- http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters. For
+-- Binary, DynamoDB treats each byte of the binary data as unsigned when it
+-- compares binary values, for example when evaluating query expressions.
+-- For information on specifying data types in JSON, see JSON Data Format in
+-- the Amazon DynamoDB Developer Guide.
+eavAttributeValueList :: Lens' ExpectedAttributeValue [AttributeValue]
+eavAttributeValueList =
+    lens _eavAttributeValueList (\s a -> s { _eavAttributeValueList = a })
+        . _List
+
+-- | A comparator for evaluating attributes in the AttributeValueList. For
+-- example, equals, greater than, less than, etc. The following comparison
+-- operators are available: EQ | NE | LE | LT | GE | GT | NOT_NULL | NULL |
+-- CONTAINS | NOT_CONTAINS | BEGINS_WITH | IN | BETWEEN The following are
+-- descriptions of each comparison operator. EQ : Equal. EQ is supported for
+-- all datatypes, including lists and maps. AttributeValueList can contain
+-- only one AttributeValue element of type String, Number, Binary, String
+-- Set, Number Set, or Binary Set. If an item contains an AttributeValue
+-- element of a different type than the one specified in the request, the
+-- value does not match. For example, {"S":"6"} does not equal {"N":"6"}.
+-- Also, {"N":"6"} does not equal {"NS":["6", "2", "1"]}. NE : Not equal. NE
+-- is supported for all datatypes, including lists and maps.
+-- AttributeValueList can contain only one AttributeValue of type String,
+-- Number, Binary, String Set, Number Set, or Binary Set. If an item
+-- contains an AttributeValue of a different type than the one specified in
+-- the request, the value does not match. For example, {"S":"6"} does not
+-- equal {"N":"6"}. Also, {"N":"6"} does not equal {"NS":["6", "2", "1"]}.
+-- LE : Less than or equal. AttributeValueList can contain only one
+-- AttributeValue element of type String, Number, or Binary (not a set
+-- type). If an item contains an AttributeValue element of a different type
+-- than the one specified in the request, the value does not match. For
+-- example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not
+-- compare to {"NS":["6", "2", "1"]}. LT : Less than. AttributeValueList can
+-- contain only one AttributeValue of type String, Number, or Binary (not a
+-- set type). If an item contains an AttributeValue element of a different
+-- type than the one specified in the request, the value does not match. For
+-- example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not
+-- compare to {"NS":["6", "2", "1"]}. GE : Greater than or equal.
+-- AttributeValueList can contain only one AttributeValue element of type
+-- String, Number, or Binary (not a set type). If an item contains an
+-- AttributeValue element of a different type than the one specified in the
+-- request, the value does not match. For example, {"S":"6"} does not equal
+-- {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", "1"]}. GT
+-- : Greater than. AttributeValueList can contain only one AttributeValue
+-- element of type String, Number, or Binary (not a set type). If an item
+-- contains an AttributeValue element of a different type than the one
+-- specified in the request, the value does not match. For example,
+-- {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not compare to
+-- {"NS":["6", "2", "1"]}. NOT_NULL : The attribute exists. NOT_NULL is
+-- supported for all datatypes, including lists and maps. NULL : The
+-- attribute does not exist. NULL is supported for all datatypes, including
+-- lists and maps. CONTAINS : Checks for a subsequence, or value in a set.
+-- AttributeValueList can contain only one AttributeValue element of type
+-- String, Number, or Binary (not a set type). If the target attribute of
+-- the comparison is of type String, then the operator checks for a
+-- substring match. If the target attribute of the comparison is of type
+-- Binary, then the operator looks for a subsequence of the target that
+-- matches the input. If the target attribute of the comparison is a set
+-- ("SS", "NS", or "BS"), then the operator evaluates to true if it finds an
+-- exact match with any member of the set. CONTAINS is supported for lists:
+-- When evaluating "a CONTAINS b", "a" can be a list; however, "b" cannot be
+-- a set, a map, or a list. NOT_CONTAINS : Checks for absence of a
+-- subsequence, or absence of a value in a set. AttributeValueList can
+-- contain only one AttributeValue element of type String, Number, or Binary
+-- (not a set type). If the target attribute of the comparison is a String,
+-- then the operator checks for the absence of a substring match. If the
+-- target attribute of the comparison is Binary, then the operator checks
+-- for the absence of a subsequence of the target that matches the input. If
+-- the target attribute of the comparison is a set ("SS", "NS", or "BS"),
+-- then the operator evaluates to true if it does not find an exact match
+-- with any member of the set. NOT_CONTAINS is supported for lists: When
+-- evaluating "a NOT CONTAINS b", "a" can be a list; however, "b" cannot be
+-- a set, a map, or a list. BEGINS_WITH : Checks for a prefix.
+-- AttributeValueList can contain only one AttributeValue of type String or
+-- Binary (not a Number or a set type). The target attribute of the
+-- comparison must be of type String or Binary (not a Number or a set type).
+-- IN : Checks for matching elements within two sets. AttributeValueList can
+-- contain one or more AttributeValue elements of type String, Number, or
+-- Binary (not a set type). These attributes are compared against an
+-- existing set type attribute of an item. If any elements of the input set
+-- are present in the item attribute, the expression evaluates to true.
+-- BETWEEN : Greater than or equal to the first value, and less than or
+-- equal to the second value. AttributeValueList must contain two
+-- AttributeValue elements of the same type, either String, Number, or
+-- Binary (not a set type). A target attribute matches if the target value
+-- is greater than, or equal to, the first element and less than, or equal
+-- to, the second element. If an item contains an AttributeValue element of
+-- a different type than the one specified in the request, the value does
+-- not match. For example, {"S":"6"} does not compare to {"N":"6"}. Also,
+-- {"N":"6"} does not compare to {"NS":["6", "2", "1"]}.
+eavComparisonOperator :: Lens' ExpectedAttributeValue (Maybe Text)
+eavComparisonOperator =
+    lens _eavComparisonOperator (\s a -> s { _eavComparisonOperator = a })
+
+-- | Causes DynamoDB to evaluate the value before attempting a conditional
+-- operation: If Exists is true, DynamoDB will check to see if that
+-- attribute value already exists in the table. If it is found, then the
+-- operation succeeds. If it is not found, the operation fails with a
+-- ConditionalCheckFailedException. If Exists is false, DynamoDB assumes
+-- that the attribute value does not exist in the table. If in fact the
+-- value does not exist, then the assumption is valid and the operation
+-- succeeds. If the value is found, despite the assumption that it does not
+-- exist, the operation fails with a ConditionalCheckFailedException. The
+-- default setting for Exists is true. If you supply a Value all by itself,
+-- DynamoDB assumes the attribute exists: You don't have to set Exists to
+-- true, because it is implied. DynamoDB returns a ValidationException if:
+-- Exists is true but there is no Value to check. (You expect a value to
+-- exist, but don't specify what that value is.) Exists is false but you
+-- also specify a Value. (You cannot expect an attribute to have a value,
+-- while also expecting it not to exist.).
+eavExists :: Lens' ExpectedAttributeValue (Maybe Bool)
+eavExists = lens _eavExists (\s a -> s { _eavExists = a })
+
+eavValue :: Lens' ExpectedAttributeValue (Maybe AttributeValue)
+eavValue = lens _eavValue (\s a -> s { _eavValue = a })
+
+instance FromJSON ExpectedAttributeValue where
+    parseJSON = withObject "ExpectedAttributeValue" $ \o -> ExpectedAttributeValue
+        <$> o .:  "AttributeValueList"
+        <*> o .:? "ComparisonOperator"
+        <*> o .:? "Exists"
+        <*> o .:? "Value"
+
+instance ToJSON ExpectedAttributeValue where
+    toJSON ExpectedAttributeValue{..} = object
+        [ "Value"              .= _eavValue
+        , "Exists"             .= _eavExists
+        , "ComparisonOperator" .= _eavComparisonOperator
+        , "AttributeValueList" .= _eavAttributeValueList
+        ]
+
+data AttributeDefinition = AttributeDefinition
+    { _adAttributeName :: Text
+    , _adAttributeType :: Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'AttributeDefinition' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'adAttributeName' @::@ 'Text'
+--
+-- * 'adAttributeType' @::@ 'Text'
+--
+attributeDefinition :: Text -- ^ 'adAttributeName'
+                    -> Text -- ^ 'adAttributeType'
+                    -> AttributeDefinition
+attributeDefinition p1 p2 = AttributeDefinition
+    { _adAttributeName = p1
+    , _adAttributeType = p2
+    }
+
+-- | A name for the attribute.
+adAttributeName :: Lens' AttributeDefinition Text
+adAttributeName = lens _adAttributeName (\s a -> s { _adAttributeName = a })
+
+-- | The data type for the attribute.
+adAttributeType :: Lens' AttributeDefinition Text
+adAttributeType = lens _adAttributeType (\s a -> s { _adAttributeType = a })
+
+instance FromJSON AttributeDefinition where
+    parseJSON = withObject "AttributeDefinition" $ \o -> AttributeDefinition
+        <$> o .:  "AttributeName"
+        <*> o .:  "AttributeType"
+
+instance ToJSON AttributeDefinition where
+    toJSON AttributeDefinition{..} = object
+        [ "AttributeName" .= _adAttributeName
+        , "AttributeType" .= _adAttributeType
+        ]
+
+data ComparisonOperator
+    = BeginsWith  -- ^ BEGINS_WITH
+    | Between     -- ^ BETWEEN
+    | Contains    -- ^ CONTAINS
+    | Eq          -- ^ EQ
+    | Ge          -- ^ GE
+    | Gt          -- ^ GT
+    | In'         -- ^ IN
+    | Le          -- ^ LE
+    | Lt          -- ^ LT
+    | Ne          -- ^ NE
+    | NotContains -- ^ NOT_CONTAINS
+    | NotNull     -- ^ NOT_NULL
+    | Null        -- ^ NULL
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable ComparisonOperator
+
+instance FromText ComparisonOperator where
+    parser = match "BEGINS_WITH"  BeginsWith
+         <|> match "BETWEEN"      Between
+         <|> match "CONTAINS"     Contains
+         <|> match "EQ"           Eq
+         <|> match "GE"           Ge
+         <|> match "GT"           Gt
+         <|> match "IN"           In'
+         <|> match "LE"           Le
+         <|> match "LT"           Lt
+         <|> match "NE"           Ne
+         <|> match "NOT_CONTAINS" NotContains
+         <|> match "NOT_NULL"     NotNull
+         <|> match "NULL"         Null
+
+instance ToText ComparisonOperator where
+    toText = \case
+        BeginsWith  -> "BEGINS_WITH"
+        Between     -> "BETWEEN"
+        Contains    -> "CONTAINS"
+        Eq          -> "EQ"
+        Ge          -> "GE"
+        Gt          -> "GT"
+        In'         -> "IN"
+        Le          -> "LE"
+        Lt          -> "LT"
+        Ne          -> "NE"
+        NotContains -> "NOT_CONTAINS"
+        NotNull     -> "NOT_NULL"
+        Null        -> "NULL"
+
+instance FromJSON ComparisonOperator where
+    parseJSON = parseJSONText "ComparisonOperator"
+
+instance ToJSON ComparisonOperator where
+    toJSON = toJSONText
+
+data ReturnValue
+    = RVAllNew     -- ^ ALL_NEW
+    | RVAllOld     -- ^ ALL_OLD
+    | RVNone       -- ^ NONE
+    | RVUpdatedNew -- ^ UPDATED_NEW
+    | RVUpdatedOld -- ^ UPDATED_OLD
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable ReturnValue
+
+instance FromText ReturnValue where
+    parser = match "ALL_NEW"     RVAllNew
+         <|> match "ALL_OLD"     RVAllOld
+         <|> match "NONE"        RVNone
+         <|> match "UPDATED_NEW" RVUpdatedNew
+         <|> match "UPDATED_OLD" RVUpdatedOld
+
+instance ToText ReturnValue where
+    toText = \case
+        RVAllNew     -> "ALL_NEW"
+        RVAllOld     -> "ALL_OLD"
+        RVNone       -> "NONE"
+        RVUpdatedNew -> "UPDATED_NEW"
+        RVUpdatedOld -> "UPDATED_OLD"
+
+instance FromJSON ReturnValue where
+    parseJSON = parseJSONText "ReturnValue"
+
+instance ToJSON ReturnValue where
+    toJSON = toJSONText
+
+data LocalSecondaryIndex = LocalSecondaryIndex
+    { _lsiIndexName  :: Text
+    , _lsiKeySchema  :: List1 "KeySchema" KeySchemaElement
+    , _lsiProjection :: Projection
+    } deriving (Eq, Show)
+
+-- | 'LocalSecondaryIndex' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'lsiIndexName' @::@ 'Text'
+--
+-- * 'lsiKeySchema' @::@ 'NonEmpty' 'KeySchemaElement'
+--
+-- * 'lsiProjection' @::@ 'Projection'
+--
+localSecondaryIndex :: Text -- ^ 'lsiIndexName'
+                    -> NonEmpty KeySchemaElement -- ^ 'lsiKeySchema'
+                    -> Projection -- ^ 'lsiProjection'
+                    -> LocalSecondaryIndex
+localSecondaryIndex p1 p2 p3 = LocalSecondaryIndex
+    { _lsiIndexName  = p1
+    , _lsiKeySchema  = withIso _List1 (const id) p2
+    , _lsiProjection = p3
+    }
+
+-- | The name of the local secondary index. The name must be unique among all
+-- other indexes on this table.
+lsiIndexName :: Lens' LocalSecondaryIndex Text
+lsiIndexName = lens _lsiIndexName (\s a -> s { _lsiIndexName = a })
+
+-- | The complete key schema for the local secondary index, consisting of one
+-- or more pairs of attribute names and key types (HASH or RANGE).
+lsiKeySchema :: Lens' LocalSecondaryIndex (NonEmpty KeySchemaElement)
+lsiKeySchema = lens _lsiKeySchema (\s a -> s { _lsiKeySchema = a }) . _List1
+
+lsiProjection :: Lens' LocalSecondaryIndex Projection
+lsiProjection = lens _lsiProjection (\s a -> s { _lsiProjection = a })
+
+instance FromJSON LocalSecondaryIndex where
+    parseJSON = withObject "LocalSecondaryIndex" $ \o -> LocalSecondaryIndex
+        <$> o .:  "IndexName"
+        <*> o .:  "KeySchema"
+        <*> o .:  "Projection"
+
+instance ToJSON LocalSecondaryIndex where
+    toJSON LocalSecondaryIndex{..} = object
+        [ "IndexName"  .= _lsiIndexName
+        , "KeySchema"  .= _lsiKeySchema
+        , "Projection" .= _lsiProjection
+        ]
+
+data GlobalSecondaryIndexDescription = GlobalSecondaryIndexDescription
+    { _gsidIndexName             :: Maybe Text
+    , _gsidIndexSizeBytes        :: Maybe Integer
+    , _gsidIndexStatus           :: Maybe Text
+    , _gsidItemCount             :: Maybe Integer
+    , _gsidKeySchema             :: List1 "KeySchema" KeySchemaElement
+    , _gsidProjection            :: Maybe Projection
+    , _gsidProvisionedThroughput :: Maybe ProvisionedThroughputDescription
+    } deriving (Eq, Show)
+
+-- | 'GlobalSecondaryIndexDescription' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'gsidIndexName' @::@ 'Maybe' 'Text'
+--
+-- * 'gsidIndexSizeBytes' @::@ 'Maybe' 'Integer'
+--
+-- * 'gsidIndexStatus' @::@ 'Maybe' 'Text'
+--
+-- * 'gsidItemCount' @::@ 'Maybe' 'Integer'
+--
+-- * 'gsidKeySchema' @::@ 'NonEmpty' 'KeySchemaElement'
+--
+-- * 'gsidProjection' @::@ 'Maybe' 'Projection'
+--
+-- * 'gsidProvisionedThroughput' @::@ 'Maybe' 'ProvisionedThroughputDescription'
+--
+globalSecondaryIndexDescription :: NonEmpty KeySchemaElement -- ^ 'gsidKeySchema'
+                                -> GlobalSecondaryIndexDescription
+globalSecondaryIndexDescription p1 = GlobalSecondaryIndexDescription
+    { _gsidKeySchema             = withIso _List1 (const id) p1
+    , _gsidIndexName             = Nothing
+    , _gsidProjection            = Nothing
+    , _gsidIndexStatus           = Nothing
+    , _gsidProvisionedThroughput = Nothing
+    , _gsidIndexSizeBytes        = Nothing
+    , _gsidItemCount             = Nothing
+    }
+
+-- | The name of the global secondary index.
+gsidIndexName :: Lens' GlobalSecondaryIndexDescription (Maybe Text)
+gsidIndexName = lens _gsidIndexName (\s a -> s { _gsidIndexName = a })
+
+-- | The total size of the specified index, in bytes. DynamoDB updates this
+-- value approximately every six hours. Recent changes might not be
+-- reflected in this value.
+gsidIndexSizeBytes :: Lens' GlobalSecondaryIndexDescription (Maybe Integer)
+gsidIndexSizeBytes =
+    lens _gsidIndexSizeBytes (\s a -> s { _gsidIndexSizeBytes = a })
+
+-- | The current state of the global secondary index: CREATING - The index is
+-- being created, as the result of a CreateTable or UpdateTable operation.
+-- UPDATING - The index is being updated, as the result of a CreateTable or
+-- UpdateTable operation. DELETING - The index is being deleted, as the
+-- result of a DeleteTable operation. ACTIVE - The index is ready for use.
+gsidIndexStatus :: Lens' GlobalSecondaryIndexDescription (Maybe Text)
+gsidIndexStatus = lens _gsidIndexStatus (\s a -> s { _gsidIndexStatus = a })
+
+-- | The number of items in the specified index. DynamoDB updates this value
+-- approximately every six hours. Recent changes might not be reflected in
+-- this value.
+gsidItemCount :: Lens' GlobalSecondaryIndexDescription (Maybe Integer)
+gsidItemCount = lens _gsidItemCount (\s a -> s { _gsidItemCount = a })
+
+-- | The complete key schema for the global secondary index, consisting of one
+-- or more pairs of attribute names and key types (HASH or RANGE).
+gsidKeySchema :: Lens' GlobalSecondaryIndexDescription (NonEmpty KeySchemaElement)
+gsidKeySchema = lens _gsidKeySchema (\s a -> s { _gsidKeySchema = a }) . _List1
+
+gsidProjection :: Lens' GlobalSecondaryIndexDescription (Maybe Projection)
+gsidProjection = lens _gsidProjection (\s a -> s { _gsidProjection = a })
+
+gsidProvisionedThroughput :: Lens' GlobalSecondaryIndexDescription (Maybe ProvisionedThroughputDescription)
+gsidProvisionedThroughput =
+    lens _gsidProvisionedThroughput
+        (\s a -> s { _gsidProvisionedThroughput = a })
+
+instance FromJSON GlobalSecondaryIndexDescription where
+    parseJSON = withObject "GlobalSecondaryIndexDescription" $ \o -> GlobalSecondaryIndexDescription
+        <$> o .:? "IndexName"
+        <*> o .:? "IndexSizeBytes"
+        <*> o .:? "IndexStatus"
+        <*> o .:? "ItemCount"
+        <*> o .:  "KeySchema"
+        <*> o .:? "Projection"
+        <*> o .:? "ProvisionedThroughput"
+
+instance ToJSON GlobalSecondaryIndexDescription where
+    toJSON GlobalSecondaryIndexDescription{..} = object
+        [ "IndexName"             .= _gsidIndexName
+        , "KeySchema"             .= _gsidKeySchema
+        , "Projection"            .= _gsidProjection
+        , "IndexStatus"           .= _gsidIndexStatus
+        , "ProvisionedThroughput" .= _gsidProvisionedThroughput
+        , "IndexSizeBytes"        .= _gsidIndexSizeBytes
+        , "ItemCount"             .= _gsidItemCount
+        ]
+
+data ItemCollectionMetrics = ItemCollectionMetrics
+    { _icmItemCollectionKey   :: Map Text AttributeValue
+    , _icmSizeEstimateRangeGB :: List "SizeEstimateRangeGB" Double
+    } deriving (Eq, Show)
+
+-- | 'ItemCollectionMetrics' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'icmItemCollectionKey' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'icmSizeEstimateRangeGB' @::@ ['Double']
+--
+itemCollectionMetrics :: ItemCollectionMetrics
+itemCollectionMetrics = ItemCollectionMetrics
+    { _icmItemCollectionKey   = mempty
+    , _icmSizeEstimateRangeGB = mempty
+    }
+
+-- | The hash key value of the item collection. This value is the same as the
+-- hash key of the item.
+icmItemCollectionKey :: Lens' ItemCollectionMetrics (HashMap Text AttributeValue)
+icmItemCollectionKey =
+    lens _icmItemCollectionKey (\s a -> s { _icmItemCollectionKey = a })
+        . _Map
+
+-- | An estimate of item collection size, in gigabytes. This value is a
+-- two-element array containing a lower bound and an upper bound for the
+-- estimate. The estimate includes the size of all the items in the table,
+-- plus the size of all attributes projected into all of the local secondary
+-- indexes on that table. Use this estimate to measure whether a local
+-- secondary index is approaching its size limit. The estimate is subject to
+-- change over time; therefore, do not rely on the precision or accuracy of
+-- the estimate.
+icmSizeEstimateRangeGB :: Lens' ItemCollectionMetrics [Double]
+icmSizeEstimateRangeGB =
+    lens _icmSizeEstimateRangeGB (\s a -> s { _icmSizeEstimateRangeGB = a })
+        . _List
+
+instance FromJSON ItemCollectionMetrics where
+    parseJSON = withObject "ItemCollectionMetrics" $ \o -> ItemCollectionMetrics
+        <$> o .:  "ItemCollectionKey"
+        <*> o .:  "SizeEstimateRangeGB"
+
+instance ToJSON ItemCollectionMetrics where
+    toJSON ItemCollectionMetrics{..} = object
+        [ "ItemCollectionKey"   .= _icmItemCollectionKey
+        , "SizeEstimateRangeGB" .= _icmSizeEstimateRangeGB
+        ]
+
+newtype Capacity = Capacity
+    { _cCapacityUnits :: Maybe Double
+    } deriving (Eq, Ord, Show)
+
+-- | 'Capacity' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'cCapacityUnits' @::@ 'Maybe' 'Double'
+--
+capacity :: Capacity
+capacity = Capacity
+    { _cCapacityUnits = Nothing
+    }
+
+-- | The total number of capacity units consumed on a table or an index.
+cCapacityUnits :: Lens' Capacity (Maybe Double)
+cCapacityUnits = lens _cCapacityUnits (\s a -> s { _cCapacityUnits = a })
+
+instance FromJSON Capacity where
+    parseJSON = withObject "Capacity" $ \o -> Capacity
+        <$> o .:? "CapacityUnits"
+
+instance ToJSON Capacity where
+    toJSON Capacity{..} = object
+        [ "CapacityUnits" .= _cCapacityUnits
+        ]
+
+data ConsumedCapacity = ConsumedCapacity
+    { _ccCapacityUnits          :: Maybe Double
+    , _ccGlobalSecondaryIndexes :: Map Text Capacity
+    , _ccLocalSecondaryIndexes  :: Map Text Capacity
+    , _ccTable                  :: Maybe Capacity
+    , _ccTableName              :: Maybe Text
+    } deriving (Eq, Show)
+
+-- | 'ConsumedCapacity' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'ccCapacityUnits' @::@ 'Maybe' 'Double'
+--
+-- * 'ccGlobalSecondaryIndexes' @::@ 'HashMap' 'Text' 'Capacity'
+--
+-- * 'ccLocalSecondaryIndexes' @::@ 'HashMap' 'Text' 'Capacity'
+--
+-- * 'ccTable' @::@ 'Maybe' 'Capacity'
+--
+-- * 'ccTableName' @::@ 'Maybe' 'Text'
+--
+consumedCapacity :: ConsumedCapacity
+consumedCapacity = ConsumedCapacity
+    { _ccTableName              = Nothing
+    , _ccCapacityUnits          = Nothing
+    , _ccTable                  = Nothing
+    , _ccLocalSecondaryIndexes  = mempty
+    , _ccGlobalSecondaryIndexes = mempty
+    }
+
+-- | The total number of capacity units consumed by the operation.
+ccCapacityUnits :: Lens' ConsumedCapacity (Maybe Double)
+ccCapacityUnits = lens _ccCapacityUnits (\s a -> s { _ccCapacityUnits = a })
+
+-- | The amount of throughput consumed on each global index affected by the
+-- operation.
+ccGlobalSecondaryIndexes :: Lens' ConsumedCapacity (HashMap Text Capacity)
+ccGlobalSecondaryIndexes =
+    lens _ccGlobalSecondaryIndexes
+        (\s a -> s { _ccGlobalSecondaryIndexes = a })
+            . _Map
+
+-- | The amount of throughput consumed on each local index affected by the
+-- operation.
+ccLocalSecondaryIndexes :: Lens' ConsumedCapacity (HashMap Text Capacity)
+ccLocalSecondaryIndexes =
+    lens _ccLocalSecondaryIndexes (\s a -> s { _ccLocalSecondaryIndexes = a })
+        . _Map
+
+-- | The amount of throughput consumed on the table affected by the operation.
+ccTable :: Lens' ConsumedCapacity (Maybe Capacity)
+ccTable = lens _ccTable (\s a -> s { _ccTable = a })
+
+-- | The name of the table that was affected by the operation.
+ccTableName :: Lens' ConsumedCapacity (Maybe Text)
+ccTableName = lens _ccTableName (\s a -> s { _ccTableName = a })
+
+instance FromJSON ConsumedCapacity where
+    parseJSON = withObject "ConsumedCapacity" $ \o -> ConsumedCapacity
+        <$> o .:? "CapacityUnits"
+        <*> o .:  "GlobalSecondaryIndexes"
+        <*> o .:  "LocalSecondaryIndexes"
+        <*> o .:? "Table"
+        <*> o .:? "TableName"
+
+instance ToJSON ConsumedCapacity where
+    toJSON ConsumedCapacity{..} = object
+        [ "TableName"              .= _ccTableName
+        , "CapacityUnits"          .= _ccCapacityUnits
+        , "Table"                  .= _ccTable
+        , "LocalSecondaryIndexes"  .= _ccLocalSecondaryIndexes
+        , "GlobalSecondaryIndexes" .= _ccGlobalSecondaryIndexes
+        ]
+
+data GlobalSecondaryIndex = GlobalSecondaryIndex
+    { _gsiIndexName             :: Text
+    , _gsiKeySchema             :: List1 "KeySchema" KeySchemaElement
+    , _gsiProjection            :: Projection
+    , _gsiProvisionedThroughput :: ProvisionedThroughput
+    } deriving (Eq, Show)
+
+-- | 'GlobalSecondaryIndex' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'gsiIndexName' @::@ 'Text'
+--
+-- * 'gsiKeySchema' @::@ 'NonEmpty' 'KeySchemaElement'
+--
+-- * 'gsiProjection' @::@ 'Projection'
+--
+-- * 'gsiProvisionedThroughput' @::@ 'ProvisionedThroughput'
+--
+globalSecondaryIndex :: Text -- ^ 'gsiIndexName'
+                     -> NonEmpty KeySchemaElement -- ^ 'gsiKeySchema'
+                     -> Projection -- ^ 'gsiProjection'
+                     -> ProvisionedThroughput -- ^ 'gsiProvisionedThroughput'
+                     -> GlobalSecondaryIndex
+globalSecondaryIndex p1 p2 p3 p4 = GlobalSecondaryIndex
+    { _gsiIndexName             = p1
+    , _gsiKeySchema             = withIso _List1 (const id) p2
+    , _gsiProjection            = p3
+    , _gsiProvisionedThroughput = p4
+    }
+
+-- | The name of the global secondary index. The name must be unique among all
+-- other indexes on this table.
+gsiIndexName :: Lens' GlobalSecondaryIndex Text
+gsiIndexName = lens _gsiIndexName (\s a -> s { _gsiIndexName = a })
+
+-- | The complete key schema for a global secondary index, which consists of
+-- one or more pairs of attribute names and key types (HASH or RANGE).
+gsiKeySchema :: Lens' GlobalSecondaryIndex (NonEmpty KeySchemaElement)
+gsiKeySchema = lens _gsiKeySchema (\s a -> s { _gsiKeySchema = a }) . _List1
+
+gsiProjection :: Lens' GlobalSecondaryIndex Projection
+gsiProjection = lens _gsiProjection (\s a -> s { _gsiProjection = a })
+
+gsiProvisionedThroughput :: Lens' GlobalSecondaryIndex ProvisionedThroughput
+gsiProvisionedThroughput =
+    lens _gsiProvisionedThroughput
+        (\s a -> s { _gsiProvisionedThroughput = a })
+
+instance FromJSON GlobalSecondaryIndex where
+    parseJSON = withObject "GlobalSecondaryIndex" $ \o -> GlobalSecondaryIndex
+        <$> o .:  "IndexName"
+        <*> o .:  "KeySchema"
+        <*> o .:  "Projection"
+        <*> o .:  "ProvisionedThroughput"
+
+instance ToJSON GlobalSecondaryIndex where
+    toJSON GlobalSecondaryIndex{..} = object
+        [ "IndexName"             .= _gsiIndexName
+        , "KeySchema"             .= _gsiKeySchema
+        , "Projection"            .= _gsiProjection
+        , "ProvisionedThroughput" .= _gsiProvisionedThroughput
+        ]
+
+data LocalSecondaryIndexDescription = LocalSecondaryIndexDescription
+    { _lsidIndexName      :: Maybe Text
+    , _lsidIndexSizeBytes :: Maybe Integer
+    , _lsidItemCount      :: Maybe Integer
+    , _lsidKeySchema      :: List1 "KeySchema" KeySchemaElement
+    , _lsidProjection     :: Maybe Projection
+    } deriving (Eq, Show)
+
+-- | 'LocalSecondaryIndexDescription' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'lsidIndexName' @::@ 'Maybe' 'Text'
+--
+-- * 'lsidIndexSizeBytes' @::@ 'Maybe' 'Integer'
+--
+-- * 'lsidItemCount' @::@ 'Maybe' 'Integer'
+--
+-- * 'lsidKeySchema' @::@ 'NonEmpty' 'KeySchemaElement'
+--
+-- * 'lsidProjection' @::@ 'Maybe' 'Projection'
+--
+localSecondaryIndexDescription :: NonEmpty KeySchemaElement -- ^ 'lsidKeySchema'
+                               -> LocalSecondaryIndexDescription
+localSecondaryIndexDescription p1 = LocalSecondaryIndexDescription
+    { _lsidKeySchema      = withIso _List1 (const id) p1
+    , _lsidIndexName      = Nothing
+    , _lsidProjection     = Nothing
+    , _lsidIndexSizeBytes = Nothing
+    , _lsidItemCount      = Nothing
+    }
+
+-- | Represents the name of the local secondary index.
+lsidIndexName :: Lens' LocalSecondaryIndexDescription (Maybe Text)
+lsidIndexName = lens _lsidIndexName (\s a -> s { _lsidIndexName = a })
+
+-- | The total size of the specified index, in bytes. DynamoDB updates this
+-- value approximately every six hours. Recent changes might not be
+-- reflected in this value.
+lsidIndexSizeBytes :: Lens' LocalSecondaryIndexDescription (Maybe Integer)
+lsidIndexSizeBytes =
+    lens _lsidIndexSizeBytes (\s a -> s { _lsidIndexSizeBytes = a })
+
+-- | The number of items in the specified index. DynamoDB updates this value
+-- approximately every six hours. Recent changes might not be reflected in
+-- this value.
+lsidItemCount :: Lens' LocalSecondaryIndexDescription (Maybe Integer)
+lsidItemCount = lens _lsidItemCount (\s a -> s { _lsidItemCount = a })
+
+-- | The complete index key schema, which consists of one or more pairs of
+-- attribute names and key types (HASH or RANGE).
+lsidKeySchema :: Lens' LocalSecondaryIndexDescription (NonEmpty KeySchemaElement)
+lsidKeySchema = lens _lsidKeySchema (\s a -> s { _lsidKeySchema = a }) . _List1
+
+lsidProjection :: Lens' LocalSecondaryIndexDescription (Maybe Projection)
+lsidProjection = lens _lsidProjection (\s a -> s { _lsidProjection = a })
+
+instance FromJSON LocalSecondaryIndexDescription where
+    parseJSON = withObject "LocalSecondaryIndexDescription" $ \o -> LocalSecondaryIndexDescription
+        <$> o .:? "IndexName"
+        <*> o .:? "IndexSizeBytes"
+        <*> o .:? "ItemCount"
+        <*> o .:  "KeySchema"
+        <*> o .:? "Projection"
+
+instance ToJSON LocalSecondaryIndexDescription where
+    toJSON LocalSecondaryIndexDescription{..} = object
+        [ "IndexName"      .= _lsidIndexName
+        , "KeySchema"      .= _lsidKeySchema
+        , "Projection"     .= _lsidProjection
+        , "IndexSizeBytes" .= _lsidIndexSizeBytes
+        , "ItemCount"      .= _lsidItemCount
+        ]
+
+data AttributeAction
+    = Add     -- ^ ADD
+    | Delete' -- ^ DELETE
+    | Put     -- ^ PUT
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable AttributeAction
+
+instance FromText AttributeAction where
+    parser = match "ADD"    Add
+         <|> match "DELETE" Delete'
+         <|> match "PUT"    Put
+
+instance ToText AttributeAction where
+    toText = \case
+        Add     -> "ADD"
+        Delete' -> "DELETE"
+        Put     -> "PUT"
+
+instance FromJSON AttributeAction where
+    parseJSON = parseJSONText "AttributeAction"
+
+instance ToJSON AttributeAction where
+    toJSON = toJSONText
+
+data ScalarAttributeType
+    = B -- ^ B
+    | N -- ^ N
+    | S -- ^ S
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable ScalarAttributeType
+
+instance FromText ScalarAttributeType where
+    parser = match "B" B
+         <|> match "N" N
+         <|> match "S" S
+
+instance ToText ScalarAttributeType where
+    toText = \case
+        B -> "B"
+        N -> "N"
+        S -> "S"
+
+instance FromJSON ScalarAttributeType where
+    parseJSON = parseJSONText "ScalarAttributeType"
+
+instance ToJSON ScalarAttributeType where
+    toJSON = toJSONText
+
+data Projection = Projection
+    { _pNonKeyAttributes :: List1 "NonKeyAttributes" Text
+    , _pProjectionType   :: Maybe Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'Projection' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'pNonKeyAttributes' @::@ 'NonEmpty' 'Text'
+--
+-- * 'pProjectionType' @::@ 'Maybe' 'Text'
+--
+projection :: NonEmpty Text -- ^ 'pNonKeyAttributes'
+           -> Projection
+projection p1 = Projection
+    { _pNonKeyAttributes = withIso _List1 (const id) p1
+    , _pProjectionType   = Nothing
+    }
+
+-- | Represents the non-key attribute names which will be projected into the
+-- index. For local secondary indexes, the total count of NonKeyAttributes
+-- summed across all of the local secondary indexes, must not exceed 20. If
+-- you project the same attribute into two different indexes, this counts as
+-- two distinct attributes when determining the total.
+pNonKeyAttributes :: Lens' Projection (NonEmpty Text)
+pNonKeyAttributes =
+    lens _pNonKeyAttributes (\s a -> s { _pNonKeyAttributes = a })
+        . _List1
+
+-- | The set of attributes that are projected into the index: KEYS_ONLY - Only
+-- the index and primary keys are projected into the index. INCLUDE - Only
+-- the specified table attributes are projected into the index. The list of
+-- projected attributes are in NonKeyAttributes. ALL - All of the table
+-- attributes are projected into the index.
+pProjectionType :: Lens' Projection (Maybe Text)
+pProjectionType = lens _pProjectionType (\s a -> s { _pProjectionType = a })
+
+instance FromJSON Projection where
+    parseJSON = withObject "Projection" $ \o -> Projection
+        <$> o .:  "NonKeyAttributes"
+        <*> o .:? "ProjectionType"
+
+instance ToJSON Projection where
+    toJSON Projection{..} = object
+        [ "ProjectionType"   .= _pProjectionType
+        , "NonKeyAttributes" .= _pNonKeyAttributes
+        ]
+
+data Select
+    = AllAttributes          -- ^ ALL_ATTRIBUTES
+    | AllProjectedAttributes -- ^ ALL_PROJECTED_ATTRIBUTES
+    | Count                  -- ^ COUNT
+    | SpecificAttributes     -- ^ SPECIFIC_ATTRIBUTES
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable Select
+
+instance FromText Select where
+    parser = match "ALL_ATTRIBUTES"           AllAttributes
+         <|> match "ALL_PROJECTED_ATTRIBUTES" AllProjectedAttributes
+         <|> match "COUNT"                    Count
+         <|> match "SPECIFIC_ATTRIBUTES"      SpecificAttributes
+
+instance ToText Select where
+    toText = \case
+        AllAttributes          -> "ALL_ATTRIBUTES"
+        AllProjectedAttributes -> "ALL_PROJECTED_ATTRIBUTES"
+        Count                  -> "COUNT"
+        SpecificAttributes     -> "SPECIFIC_ATTRIBUTES"
+
+instance FromJSON Select where
+    parseJSON = parseJSONText "Select"
+
+instance ToJSON Select where
+    toJSON = toJSONText
+
+data KeySchemaElement = KeySchemaElement
+    { _kseAttributeName :: Text
+    , _kseKeyType       :: Text
+    } deriving (Eq, Ord, Show)
+
+-- | 'KeySchemaElement' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'kseAttributeName' @::@ 'Text'
+--
+-- * 'kseKeyType' @::@ 'Text'
+--
+keySchemaElement :: Text -- ^ 'kseAttributeName'
+                 -> Text -- ^ 'kseKeyType'
+                 -> KeySchemaElement
+keySchemaElement p1 p2 = KeySchemaElement
+    { _kseAttributeName = p1
+    , _kseKeyType       = p2
+    }
+
+-- | The name of a key attribute.
+kseAttributeName :: Lens' KeySchemaElement Text
+kseAttributeName = lens _kseAttributeName (\s a -> s { _kseAttributeName = a })
+
+-- | The attribute data, consisting of the data type and the attribute value
+-- itself.
+kseKeyType :: Lens' KeySchemaElement Text
+kseKeyType = lens _kseKeyType (\s a -> s { _kseKeyType = a })
+
+instance FromJSON KeySchemaElement where
+    parseJSON = withObject "KeySchemaElement" $ \o -> KeySchemaElement
+        <$> o .:  "AttributeName"
+        <*> o .:  "KeyType"
+
+instance ToJSON KeySchemaElement where
+    toJSON KeySchemaElement{..} = object
+        [ "AttributeName" .= _kseAttributeName
+        , "KeyType"       .= _kseKeyType
+        ]
+
+newtype DeleteRequest = DeleteRequest
+    { _dKey :: Map Text AttributeValue
+    } deriving (Eq, Show, Monoid, Semigroup)
+
+-- | 'DeleteRequest' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'dKey' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+deleteRequest :: DeleteRequest
+deleteRequest = DeleteRequest
+    { _dKey = mempty
+    }
+
+-- | A map of attribute name to attribute values, representing the primary key
+-- of the item to delete. All of the table's primary key attributes must be
+-- specified, and their data types must match those of the table's key
+-- schema.
+dKey :: Lens' DeleteRequest (HashMap Text AttributeValue)
+dKey = lens _dKey (\s a -> s { _dKey = a }) . _Map
+
+instance FromJSON DeleteRequest where
+    parseJSON = withObject "DeleteRequest" $ \o -> DeleteRequest
+        <$> o .:  "Key"
+
+instance ToJSON DeleteRequest where
+    toJSON DeleteRequest{..} = object
+        [ "Key" .= _dKey
+        ]
+
+data UpdateGlobalSecondaryIndexAction = UpdateGlobalSecondaryIndexAction
+    { _ugsiaIndexName             :: Text
+    , _ugsiaProvisionedThroughput :: ProvisionedThroughput
+    } deriving (Eq, Show)
+
+-- | 'UpdateGlobalSecondaryIndexAction' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'ugsiaIndexName' @::@ 'Text'
+--
+-- * 'ugsiaProvisionedThroughput' @::@ 'ProvisionedThroughput'
+--
+updateGlobalSecondaryIndexAction :: Text -- ^ 'ugsiaIndexName'
+                                 -> ProvisionedThroughput -- ^ 'ugsiaProvisionedThroughput'
+                                 -> UpdateGlobalSecondaryIndexAction
+updateGlobalSecondaryIndexAction p1 p2 = UpdateGlobalSecondaryIndexAction
+    { _ugsiaIndexName             = p1
+    , _ugsiaProvisionedThroughput = p2
+    }
+
+-- | The name of the global secondary index to be updated.
+ugsiaIndexName :: Lens' UpdateGlobalSecondaryIndexAction Text
+ugsiaIndexName = lens _ugsiaIndexName (\s a -> s { _ugsiaIndexName = a })
+
+ugsiaProvisionedThroughput :: Lens' UpdateGlobalSecondaryIndexAction ProvisionedThroughput
+ugsiaProvisionedThroughput =
+    lens _ugsiaProvisionedThroughput
+        (\s a -> s { _ugsiaProvisionedThroughput = a })
+
+instance FromJSON UpdateGlobalSecondaryIndexAction where
+    parseJSON = withObject "UpdateGlobalSecondaryIndexAction" $ \o -> UpdateGlobalSecondaryIndexAction
+        <$> o .:  "IndexName"
+        <*> o .:  "ProvisionedThroughput"
+
+instance ToJSON UpdateGlobalSecondaryIndexAction where
+    toJSON UpdateGlobalSecondaryIndexAction{..} = object
+        [ "IndexName"             .= _ugsiaIndexName
+        , "ProvisionedThroughput" .= _ugsiaProvisionedThroughput
+        ]
+
+newtype PutRequest = PutRequest
+    { _pItem :: Map Text AttributeValue
+    } deriving (Eq, Show, Monoid, Semigroup)
+
+-- | 'PutRequest' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'pItem' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+putRequest :: PutRequest
+putRequest = PutRequest
+    { _pItem = mempty
+    }
+
+-- | A map of attribute name to attribute values, representing the primary key
+-- of an item to be processed by PutItem. All of the table's primary key
+-- attributes must be specified, and their data types must match those of
+-- the table's key schema. If any attributes are present in the item which
+-- are part of an index key schema for the table, their types must match the
+-- index key schema.
+pItem :: Lens' PutRequest (HashMap Text AttributeValue)
+pItem = lens _pItem (\s a -> s { _pItem = a }) . _Map
+
+instance FromJSON PutRequest where
+    parseJSON = withObject "PutRequest" $ \o -> PutRequest
+        <$> o .:  "Item"
+
+instance ToJSON PutRequest where
+    toJSON PutRequest{..} = object
+        [ "Item" .= _pItem
+        ]
+
+data Condition = Condition
+    { _cAttributeValueList :: List "AttributeValueList" AttributeValue
+    , _cComparisonOperator :: Text
+    } deriving (Eq, Show)
+
+-- | 'Condition' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'cAttributeValueList' @::@ ['AttributeValue']
+--
+-- * 'cComparisonOperator' @::@ 'Text'
+--
+condition :: Text -- ^ 'cComparisonOperator'
+          -> Condition
+condition p1 = Condition
+    { _cComparisonOperator = p1
+    , _cAttributeValueList = mempty
+    }
+
+-- | One or more values to evaluate against the supplied attribute. The number
+-- of values in the list depends on the ComparisonOperator being used. For
+-- type Number, value comparisons are numeric. String value comparisons for
+-- greater than, equals, or less than are based on ASCII character code
+-- values. For example, a is greater than A, and aa is greater than B. For a
+-- list of code values, see
+-- http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters. For
+-- Binary, DynamoDB treats each byte of the binary data as unsigned when it
+-- compares binary values, for example when evaluating query expressions.
+cAttributeValueList :: Lens' Condition [AttributeValue]
+cAttributeValueList =
+    lens _cAttributeValueList (\s a -> s { _cAttributeValueList = a })
+        . _List
+
+-- | A comparator for evaluating attributes. For example, equals, greater
+-- than, less than, etc. The following comparison operators are available:
+-- EQ | NE | LE | LT | GE | GT | NOT_NULL | NULL | CONTAINS | NOT_CONTAINS |
+-- BEGINS_WITH | IN | BETWEEN The following are descriptions of each
+-- comparison operator. EQ : Equal. EQ is supported for all datatypes,
+-- including lists and maps. AttributeValueList can contain only one
+-- AttributeValue element of type String, Number, Binary, String Set, Number
+-- Set, or Binary Set. If an item contains an AttributeValue element of a
+-- different type than the one specified in the request, the value does not
+-- match. For example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"}
+-- does not equal {"NS":["6", "2", "1"]}. NE : Not equal. NE is supported
+-- for all datatypes, including lists and maps. AttributeValueList can
+-- contain only one AttributeValue of type String, Number, Binary, String
+-- Set, Number Set, or Binary Set. If an item contains an AttributeValue of
+-- a different type than the one specified in the request, the value does
+-- not match. For example, {"S":"6"} does not equal {"N":"6"}. Also,
+-- {"N":"6"} does not equal {"NS":["6", "2", "1"]}. LE : Less than or equal.
+-- AttributeValueList can contain only one AttributeValue element of type
+-- String, Number, or Binary (not a set type). If an item contains an
+-- AttributeValue element of a different type than the one specified in the
+-- request, the value does not match. For example, {"S":"6"} does not equal
+-- {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", "1"]}. LT
+-- : Less than. AttributeValueList can contain only one AttributeValue of
+-- type String, Number, or Binary (not a set type). If an item contains an
+-- AttributeValue element of a different type than the one specified in the
+-- request, the value does not match. For example, {"S":"6"} does not equal
+-- {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", "1"]}. GE
+-- : Greater than or equal. AttributeValueList can contain only one
+-- AttributeValue element of type String, Number, or Binary (not a set
+-- type). If an item contains an AttributeValue element of a different type
+-- than the one specified in the request, the value does not match. For
+-- example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not
+-- compare to {"NS":["6", "2", "1"]}. GT : Greater than. AttributeValueList
+-- can contain only one AttributeValue element of type String, Number, or
+-- Binary (not a set type). If an item contains an AttributeValue element of
+-- a different type than the one specified in the request, the value does
+-- not match. For example, {"S":"6"} does not equal {"N":"6"}. Also,
+-- {"N":"6"} does not compare to {"NS":["6", "2", "1"]}. NOT_NULL : The
+-- attribute exists. NOT_NULL is supported for all datatypes, including
+-- lists and maps. NULL : The attribute does not exist. NULL is supported
+-- for all datatypes, including lists and maps. CONTAINS : Checks for a
+-- subsequence, or value in a set. AttributeValueList can contain only one
+-- AttributeValue element of type String, Number, or Binary (not a set
+-- type). If the target attribute of the comparison is of type String, then
+-- the operator checks for a substring match. If the target attribute of the
+-- comparison is of type Binary, then the operator looks for a subsequence
+-- of the target that matches the input. If the target attribute of the
+-- comparison is a set ("SS", "NS", or "BS"), then the operator evaluates to
+-- true if it finds an exact match with any member of the set. CONTAINS is
+-- supported for lists: When evaluating "a CONTAINS b", "a" can be a list;
+-- however, "b" cannot be a set, a map, or a list. NOT_CONTAINS : Checks for
+-- absence of a subsequence, or absence of a value in a set.
+-- AttributeValueList can contain only one AttributeValue element of type
+-- String, Number, or Binary (not a set type). If the target attribute of
+-- the comparison is a String, then the operator checks for the absence of a
+-- substring match. If the target attribute of the comparison is Binary,
+-- then the operator checks for the absence of a subsequence of the target
+-- that matches the input. If the target attribute of the comparison is a
+-- set ("SS", "NS", or "BS"), then the operator evaluates to true if it does
+-- not find an exact match with any member of the set. NOT_CONTAINS is
+-- supported for lists: When evaluating "a NOT CONTAINS b", "a" can be a
+-- list; however, "b" cannot be a set, a map, or a list. BEGINS_WITH :
+-- Checks for a prefix. AttributeValueList can contain only one
+-- AttributeValue of type String or Binary (not a Number or a set type). The
+-- target attribute of the comparison must be of type String or Binary (not
+-- a Number or a set type). IN : Checks for matching elements within two
+-- sets. AttributeValueList can contain one or more AttributeValue elements
+-- of type String, Number, or Binary (not a set type). These attributes are
+-- compared against an existing set type attribute of an item. If any
+-- elements of the input set are present in the item attribute, the
+-- expression evaluates to true. BETWEEN : Greater than or equal to the
+-- first value, and less than or equal to the second value.
+-- AttributeValueList must contain two AttributeValue elements of the same
+-- type, either String, Number, or Binary (not a set type). A target
+-- attribute matches if the target value is greater than, or equal to, the
+-- first element and less than, or equal to, the second element. If an item
+-- contains an AttributeValue element of a different type than the one
+-- specified in the request, the value does not match. For example,
+-- {"S":"6"} does not compare to {"N":"6"}. Also, {"N":"6"} does not compare
+-- to {"NS":["6", "2", "1"]} For usage examples of AttributeValueList and
+-- ComparisonOperator, see Legacy Conditional Parameters in the Amazon
+-- DynamoDB Developer Guide.
+cComparisonOperator :: Lens' Condition Text
+cComparisonOperator =
+    lens _cComparisonOperator (\s a -> s { _cComparisonOperator = a })
+
+instance FromJSON Condition where
+    parseJSON = withObject "Condition" $ \o -> Condition
+        <$> o .:  "AttributeValueList"
+        <*> o .:  "ComparisonOperator"
+
+instance ToJSON Condition where
+    toJSON Condition{..} = object
+        [ "AttributeValueList" .= _cAttributeValueList
+        , "ComparisonOperator" .= _cComparisonOperator
+        ]
+
+data ConditionalOperator
+    = And -- ^ AND
+    | Or  -- ^ OR
+      deriving (Eq, Ord, Show, Generic, Enum)
+
+instance Hashable ConditionalOperator
+
+instance FromText ConditionalOperator where
+    parser = match "AND" And
+         <|> match "OR"  Or
+
+instance ToText ConditionalOperator where
+    toText = \case
+        And -> "AND"
+        Or  -> "OR"
+
+instance FromJSON ConditionalOperator where
+    parseJSON = parseJSONText "ConditionalOperator"
+
+instance ToJSON ConditionalOperator where
+    toJSON = toJSONText
+
+newtype GlobalSecondaryIndexUpdate = GlobalSecondaryIndexUpdate
+    { _gsiuUpdate :: Maybe UpdateGlobalSecondaryIndexAction
+    } deriving (Eq, Show)
+
+-- | 'GlobalSecondaryIndexUpdate' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'gsiuUpdate' @::@ 'Maybe' 'UpdateGlobalSecondaryIndexAction'
+--
+globalSecondaryIndexUpdate :: GlobalSecondaryIndexUpdate
+globalSecondaryIndexUpdate = GlobalSecondaryIndexUpdate
+    { _gsiuUpdate = Nothing
+    }
+
+-- | The name of a global secondary index, along with the updated provisioned
+-- throughput settings that are to be applied to that index.
+gsiuUpdate :: Lens' GlobalSecondaryIndexUpdate (Maybe UpdateGlobalSecondaryIndexAction)
+gsiuUpdate = lens _gsiuUpdate (\s a -> s { _gsiuUpdate = a })
+
+instance FromJSON GlobalSecondaryIndexUpdate where
+    parseJSON = withObject "GlobalSecondaryIndexUpdate" $ \o -> GlobalSecondaryIndexUpdate
+        <$> o .:? "Update"
+
+instance ToJSON GlobalSecondaryIndexUpdate where
+    toJSON GlobalSecondaryIndexUpdate{..} = object
+        [ "Update" .= _gsiuUpdate
+        ]
diff --git a/gen/Network/AWS/DynamoDB/UpdateItem.hs b/gen/Network/AWS/DynamoDB/UpdateItem.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/UpdateItem.hs
@@ -0,0 +1,517 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.UpdateItem
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Edits an existing item's attributes, or adds a new item to the table if it
+-- does not already exist. You can put, delete, or add attribute values. You
+-- can also perform a conditional update (insert a new attribute name-value
+-- pair if it doesn't exist, or replace an existing name-value pair if it has
+-- certain expected attribute values). You can also return the item's
+-- attribute values in the same UpdateItem operation using the ReturnValues
+-- parameter.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html>
+module Network.AWS.DynamoDB.UpdateItem
+    (
+    -- * Request
+      UpdateItem
+    -- ** Request constructor
+    , updateItem
+    -- ** Request lenses
+    , uiAttributeUpdates
+    , uiConditionExpression
+    , uiConditionalOperator
+    , uiExpected
+    , uiExpressionAttributeNames
+    , uiExpressionAttributeValues
+    , uiKey
+    , uiReturnConsumedCapacity
+    , uiReturnItemCollectionMetrics
+    , uiReturnValues
+    , uiTableName
+    , uiUpdateExpression
+
+    -- * Response
+    , UpdateItemResponse
+    -- ** Response constructor
+    , updateItemResponse
+    -- ** Response lenses
+    , uirAttributes
+    , uirConsumedCapacity
+    , uirItemCollectionMetrics
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+data UpdateItem = UpdateItem
+    { _uiAttributeUpdates            :: Map Text AttributeValueUpdate
+    , _uiConditionExpression         :: Maybe Text
+    , _uiConditionalOperator         :: Maybe Text
+    , _uiExpected                    :: Map Text ExpectedAttributeValue
+    , _uiExpressionAttributeNames    :: Map Text Text
+    , _uiExpressionAttributeValues   :: Map Text AttributeValue
+    , _uiKey                         :: Map Text AttributeValue
+    , _uiReturnConsumedCapacity      :: Maybe Text
+    , _uiReturnItemCollectionMetrics :: Maybe Text
+    , _uiReturnValues                :: Maybe Text
+    , _uiTableName                   :: Text
+    , _uiUpdateExpression            :: Maybe Text
+    } deriving (Eq, Show)
+
+-- | 'UpdateItem' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'uiAttributeUpdates' @::@ 'HashMap' 'Text' 'AttributeValueUpdate'
+--
+-- * 'uiConditionExpression' @::@ 'Maybe' 'Text'
+--
+-- * 'uiConditionalOperator' @::@ 'Maybe' 'Text'
+--
+-- * 'uiExpected' @::@ 'HashMap' 'Text' 'ExpectedAttributeValue'
+--
+-- * 'uiExpressionAttributeNames' @::@ 'HashMap' 'Text' 'Text'
+--
+-- * 'uiExpressionAttributeValues' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'uiKey' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'uiReturnConsumedCapacity' @::@ 'Maybe' 'Text'
+--
+-- * 'uiReturnItemCollectionMetrics' @::@ 'Maybe' 'Text'
+--
+-- * 'uiReturnValues' @::@ 'Maybe' 'Text'
+--
+-- * 'uiTableName' @::@ 'Text'
+--
+-- * 'uiUpdateExpression' @::@ 'Maybe' 'Text'
+--
+updateItem :: Text -- ^ 'uiTableName'
+           -> UpdateItem
+updateItem p1 = UpdateItem
+    { _uiTableName                   = p1
+    , _uiKey                         = mempty
+    , _uiAttributeUpdates            = mempty
+    , _uiExpected                    = mempty
+    , _uiConditionalOperator         = Nothing
+    , _uiReturnValues                = Nothing
+    , _uiReturnConsumedCapacity      = Nothing
+    , _uiReturnItemCollectionMetrics = Nothing
+    , _uiUpdateExpression            = Nothing
+    , _uiConditionExpression         = Nothing
+    , _uiExpressionAttributeNames    = mempty
+    , _uiExpressionAttributeValues   = mempty
+    }
+
+-- | There is a newer parameter available. Use UpdateExpression instead. Note
+-- that if you use AttributeUpdates and UpdateExpression at the same time,
+-- DynamoDB will return a ValidationException exception. This parameter can
+-- be used for modifying top-level attributes; however, it does not support
+-- individual list or map elements. The names of attributes to be modified,
+-- the action to perform on each, and the new value for each. If you are
+-- updating an attribute that is an index key attribute for any indexes on
+-- that table, the attribute type must match the index key type defined in
+-- the AttributesDefinition of the table description. You can use UpdateItem
+-- to update any nonkey attributes. Attribute values cannot be null. String
+-- and Binary type attributes must have lengths greater than zero. Set type
+-- attributes must not be empty. Requests with empty values will be rejected
+-- with a ValidationException exception. Each AttributeUpdates element
+-- consists of an attribute name to modify, along with the following: Value
+-- - The new value, if applicable, for this attribute. Action - A value that
+-- specifies how to perform the update. This action is only valid for an
+-- existing attribute whose data type is Number or is a set; do not use ADD
+-- for other data types. If an item with the specified primary key is found
+-- in the table, the following values perform the following actions: PUT -
+-- Adds the specified attribute to the item. If the attribute already
+-- exists, it is replaced by the new value. DELETE - Removes the attribute
+-- and its value, if no value is specified for DELETE. The data type of the
+-- specified value must match the existing value's data type. If a set of
+-- values is specified, then those values are subtracted from the old set.
+-- For example, if the attribute value was the set [a,b,c] and the DELETE
+-- action specifies [a,c], then the final attribute value is [b]. Specifying
+-- an empty set is an error. ADD - Adds the specified value to the item, if
+-- the attribute does not already exist. If the attribute does exist, then
+-- the behavior of ADD depends on the data type of the attribute: If the
+-- existing attribute is a number, and if Value is also a number, then Value
+-- is mathematically added to the existing attribute. If Value is a negative
+-- number, then it is subtracted from the existing attribute. If the
+-- existing data type is a set, and if Value is also a set, then Value is
+-- appended to the existing set. For example, if the attribute value is the
+-- set [1,2], and the ADD action specified [3], then the final attribute
+-- value is [1,2,3]. An error occurs if an ADD action is specified for a set
+-- attribute and the attribute type specified does not match the existing
+-- set type. Both sets must have the same primitive data type. For example,
+-- if the existing data type is a set of strings, Value must also be a set
+-- of strings. If no item with the specified key is found in the table, the
+-- following values perform the following actions: PUT - Causes DynamoDB to
+-- create a new item with the specified primary key, and then adds the
+-- attribute. DELETE - Causes nothing to happen; there is no attribute to
+-- delete. ADD - Causes DynamoDB to creat an item with the supplied primary
+-- key and number (or set of numbers) for the attribute value. The only data
+-- types allowed are Number and Number Set. If you specify any attributes
+-- that are part of an index key, then the data types for those attributes
+-- must match those of the schema in the table's attribute definition.
+uiAttributeUpdates :: Lens' UpdateItem (HashMap Text AttributeValueUpdate)
+uiAttributeUpdates =
+    lens _uiAttributeUpdates (\s a -> s { _uiAttributeUpdates = a })
+        . _Map
+
+-- | A condition that must be satisfied in order for a conditional update to
+-- succeed. An expression can contain any of the following: Boolean
+-- functions: ATTRIBUTE_EXIST | CONTAINS | BEGINS_WITH Comparison operators:
+-- = | &#x3C;&#x3E; | &#x3C; | &#x3E; | &#x3C;= | &#x3E;= | BETWEEN | IN
+-- Logical operators: NOT | AND | OR.
+uiConditionExpression :: Lens' UpdateItem (Maybe Text)
+uiConditionExpression =
+    lens _uiConditionExpression (\s a -> s { _uiConditionExpression = a })
+
+-- | There is a newer parameter available. Use ConditionExpression instead.
+-- Note that if you use ConditionalOperator and ConditionExpression at the
+-- same time, DynamoDB will return a ValidationException exception. This
+-- parameter does not support lists or maps. A logical operator to apply to
+-- the conditions in the Expected map: AND - If all of the conditions
+-- evaluate to true, then the entire map evaluates to true. OR - If at least
+-- one of the conditions evaluate to true, then the entire map evaluates to
+-- true. If you omit ConditionalOperator, then AND is the default. The
+-- operation will succeed only if the entire map evaluates to true.
+uiConditionalOperator :: Lens' UpdateItem (Maybe Text)
+uiConditionalOperator =
+    lens _uiConditionalOperator (\s a -> s { _uiConditionalOperator = a })
+
+-- | There is a newer parameter available. Use ConditionExpression instead.
+-- Note that if you use Expected and ConditionExpression at the same time,
+-- DynamoDB will return a ValidationException exception. This parameter does
+-- not support lists or maps. A map of attribute/condition pairs. Expected
+-- provides a conditional block for the UpdateItem operation. Each element
+-- of Expected consists of an attribute name, a comparison operator, and one
+-- or more values. DynamoDB compares the attribute with the value(s) you
+-- supplied, using the comparison operator. For each Expected element, the
+-- result of the evaluation is either true or false. If you specify more
+-- than one element in the Expected map, then by default all of the
+-- conditions must evaluate to true. In other words, the conditions are
+-- ANDed together. (You can use the ConditionalOperator parameter to OR the
+-- conditions instead. If you do this, then at least one of the conditions
+-- must evaluate to true, rather than all of them.) If the Expected map
+-- evaluates to true, then the conditional operation succeeds; otherwise, it
+-- fails. Expected contains the following: AttributeValueList - One or more
+-- values to evaluate against the supplied attribute. The number of values
+-- in the list depends on the ComparisonOperator being used. For type
+-- Number, value comparisons are numeric. String value comparisons for
+-- greater than, equals, or less than are based on ASCII character code
+-- values. For example, a is greater than A, and aa is greater than B. For a
+-- list of code values, see
+-- http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters. For type
+-- Binary, DynamoDB treats each byte of the binary data as unsigned when it
+-- compares binary values, for example when evaluating query expressions.
+-- ComparisonOperator - A comparator for evaluating attributes in the
+-- AttributeValueList. When performing the comparison, DynamoDB uses
+-- strongly consistent reads. The following comparison operators are
+-- available: EQ | NE | LE | LT | GE | GT | NOT_NULL | NULL | CONTAINS |
+-- NOT_CONTAINS | BEGINS_WITH | IN | BETWEEN The following are descriptions
+-- of each comparison operator. EQ : Equal. EQ is supported for all
+-- datatypes, including lists and maps. AttributeValueList can contain only
+-- one AttributeValue element of type String, Number, Binary, String Set,
+-- Number Set, or Binary Set. If an item contains an AttributeValue element
+-- of a different type than the one specified in the request, the value does
+-- not match. For example, {"S":"6"} does not equal {"N":"6"}. Also,
+-- {"N":"6"} does not equal {"NS":["6", "2", "1"]}. NE : Not equal. NE is
+-- supported for all datatypes, including lists and maps. AttributeValueList
+-- can contain only one AttributeValue of type String, Number, Binary,
+-- String Set, Number Set, or Binary Set. If an item contains an
+-- AttributeValue of a different type than the one specified in the request,
+-- the value does not match. For example, {"S":"6"} does not equal
+-- {"N":"6"}. Also, {"N":"6"} does not equal {"NS":["6", "2", "1"]}. LE :
+-- Less than or equal. AttributeValueList can contain only one
+-- AttributeValue element of type String, Number, or Binary (not a set
+-- type). If an item contains an AttributeValue element of a different type
+-- than the one specified in the request, the value does not match. For
+-- example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not
+-- compare to {"NS":["6", "2", "1"]}. LT : Less than. AttributeValueList can
+-- contain only one AttributeValue of type String, Number, or Binary (not a
+-- set type). If an item contains an AttributeValue element of a different
+-- type than the one specified in the request, the value does not match. For
+-- example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not
+-- compare to {"NS":["6", "2", "1"]}. GE : Greater than or equal.
+-- AttributeValueList can contain only one AttributeValue element of type
+-- String, Number, or Binary (not a set type). If an item contains an
+-- AttributeValue element of a different type than the one specified in the
+-- request, the value does not match. For example, {"S":"6"} does not equal
+-- {"N":"6"}. Also, {"N":"6"} does not compare to {"NS":["6", "2", "1"]}. GT
+-- : Greater than. AttributeValueList can contain only one AttributeValue
+-- element of type String, Number, or Binary (not a set type). If an item
+-- contains an AttributeValue element of a different type than the one
+-- specified in the request, the value does not match. For example,
+-- {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not compare to
+-- {"NS":["6", "2", "1"]}. NOT_NULL : The attribute exists. NOT_NULL is
+-- supported for all datatypes, including lists and maps. NULL : The
+-- attribute does not exist. NULL is supported for all datatypes, including
+-- lists and maps. CONTAINS : Checks for a subsequence, or value in a set.
+-- AttributeValueList can contain only one AttributeValue element of type
+-- String, Number, or Binary (not a set type). If the target attribute of
+-- the comparison is of type String, then the operator checks for a
+-- substring match. If the target attribute of the comparison is of type
+-- Binary, then the operator looks for a subsequence of the target that
+-- matches the input. If the target attribute of the comparison is a set
+-- ("SS", "NS", or "BS"), then the operator evaluates to true if it finds an
+-- exact match with any member of the set. CONTAINS is supported for lists:
+-- When evaluating "a CONTAINS b", "a" can be a list; however, "b" cannot be
+-- a set, a map, or a list. NOT_CONTAINS : Checks for absence of a
+-- subsequence, or absence of a value in a set. AttributeValueList can
+-- contain only one AttributeValue element of type String, Number, or Binary
+-- (not a set type). If the target attribute of the comparison is a String,
+-- then the operator checks for the absence of a substring match. If the
+-- target attribute of the comparison is Binary, then the operator checks
+-- for the absence of a subsequence of the target that matches the input. If
+-- the target attribute of the comparison is a set ("SS", "NS", or "BS"),
+-- then the operator evaluates to true if it does not find an exact match
+-- with any member of the set. NOT_CONTAINS is supported for lists: When
+-- evaluating "a NOT CONTAINS b", "a" can be a list; however, "b" cannot be
+-- a set, a map, or a list. BEGINS_WITH : Checks for a prefix.
+-- AttributeValueList can contain only one AttributeValue of type String or
+-- Binary (not a Number or a set type). The target attribute of the
+-- comparison must be of type String or Binary (not a Number or a set type).
+-- IN : Checks for matching elements within two sets. AttributeValueList can
+-- contain one or more AttributeValue elements of type String, Number, or
+-- Binary (not a set type). These attributes are compared against an
+-- existing set type attribute of an item. If any elements of the input set
+-- are present in the item attribute, the expression evaluates to true.
+-- BETWEEN : Greater than or equal to the first value, and less than or
+-- equal to the second value. AttributeValueList must contain two
+-- AttributeValue elements of the same type, either String, Number, or
+-- Binary (not a set type). A target attribute matches if the target value
+-- is greater than, or equal to, the first element and less than, or equal
+-- to, the second element. If an item contains an AttributeValue element of
+-- a different type than the one specified in the request, the value does
+-- not match. For example, {"S":"6"} does not compare to {"N":"6"}. Also,
+-- {"N":"6"} does not compare to {"NS":["6", "2", "1"]} For usage examples
+-- of AttributeValueList and ComparisonOperator, see Legacy Conditional
+-- Parameters in the Amazon DynamoDB Developer Guide. For backward
+-- compatibility with previous DynamoDB releases, the following parameters
+-- can be used instead of AttributeValueList and ComparisonOperator: Value -
+-- A value for DynamoDB to compare with an attribute. Exists - A Boolean
+-- value that causes DynamoDB to evaluate the value before attempting the
+-- conditional operation: If Exists is true, DynamoDB will check to see if
+-- that attribute value already exists in the table. If it is found, then
+-- the condition evaluates to true; otherwise the condition evaluate to
+-- false. If Exists is false, DynamoDB assumes that the attribute value does
+-- not exist in the table. If in fact the value does not exist, then the
+-- assumption is valid and the condition evaluates to true. If the value is
+-- found, despite the assumption that it does not exist, the condition
+-- evaluates to false. The Value and Exists parameters are incompatible with
+-- AttributeValueList and ComparisonOperator. Note that if you use both sets
+-- of parameters at once, DynamoDB will return a ValidationException
+-- exception.
+uiExpected :: Lens' UpdateItem (HashMap Text ExpectedAttributeValue)
+uiExpected = lens _uiExpected (\s a -> s { _uiExpected = a }) . _Map
+
+-- | One or more substitution tokens for simplifying complex expressions. The
+-- following are some use cases for an ExpressionAttributeNames value: To
+-- shorten an attribute name that is very long or unwieldy in an expression.
+-- To create a placeholder for repeating occurrences of an attribute name in
+-- an expression. To prevent special characters in an attribute name from
+-- being misinterpreted in an expression. Use the # character in an
+-- expression to dereference an attribute name. For example, consider the
+-- following expression: order.customerInfo.LastName = "Smith" OR
+-- order.customerInfo.LastName = "Jones" Now suppose that you specified the
+-- following for ExpressionAttributeNames:
+-- {"n":"order.customerInfo.LastName"} The expression can now be simplified
+-- as follows: #n = "Smith" OR #n = "Jones".
+uiExpressionAttributeNames :: Lens' UpdateItem (HashMap Text Text)
+uiExpressionAttributeNames =
+    lens _uiExpressionAttributeNames
+        (\s a -> s { _uiExpressionAttributeNames = a })
+            . _Map
+
+-- | One or more values that can be substituted in an expression. Use the :
+-- character in an expression to dereference an attribute value. For
+-- example, consider the following expression: ProductStatus IN
+-- ("Available","Backordered","Discontinued") Now suppose that you specified
+-- the following for ExpressionAttributeValues: { "a":{"S":"Available"},
+-- "b":{"S":"Backordered"}, "d":{"S":"Discontinued"} } The expression can
+-- now be simplified as follows: ProductStatus IN (:a,:b,:c).
+uiExpressionAttributeValues :: Lens' UpdateItem (HashMap Text AttributeValue)
+uiExpressionAttributeValues =
+    lens _uiExpressionAttributeValues
+        (\s a -> s { _uiExpressionAttributeValues = a })
+            . _Map
+
+-- | The primary key of the item to be updated. Each element consists of an
+-- attribute name and a value for that attribute. For the primary key, you
+-- must provide all of the attributes. For example, with a hash type primary
+-- key, you only need to specify the hash attribute. For a hash-and-range
+-- type primary key, you must specify both the hash attribute and the range
+-- attribute.
+uiKey :: Lens' UpdateItem (HashMap Text AttributeValue)
+uiKey = lens _uiKey (\s a -> s { _uiKey = a }) . _Map
+
+uiReturnConsumedCapacity :: Lens' UpdateItem (Maybe Text)
+uiReturnConsumedCapacity =
+    lens _uiReturnConsumedCapacity
+        (\s a -> s { _uiReturnConsumedCapacity = a })
+
+-- | A value that if set to SIZE, the response includes statistics about item
+-- collections, if any, that were modified during the operation are returned
+-- in the response. If set to NONE (the default), no statistics are
+-- returned.
+uiReturnItemCollectionMetrics :: Lens' UpdateItem (Maybe Text)
+uiReturnItemCollectionMetrics =
+    lens _uiReturnItemCollectionMetrics
+        (\s a -> s { _uiReturnItemCollectionMetrics = a })
+
+-- | Use ReturnValues if you want to get the item attributes as they appeared
+-- either before or after they were updated. For UpdateItem, the valid
+-- values are: NONE - If ReturnValues is not specified, or if its value is
+-- NONE, then nothing is returned. (This setting is the default for
+-- ReturnValues.) ALL_OLD - If UpdateItem overwrote an attribute name-value
+-- pair, then the content of the old item is returned. UPDATED_OLD - The old
+-- versions of only the updated attributes are returned. ALL_NEW - All of
+-- the attributes of the new version of the item are returned. UPDATED_NEW -
+-- The new versions of only the updated attributes are returned.
+uiReturnValues :: Lens' UpdateItem (Maybe Text)
+uiReturnValues = lens _uiReturnValues (\s a -> s { _uiReturnValues = a })
+
+-- | The name of the table containing the item to update.
+uiTableName :: Lens' UpdateItem Text
+uiTableName = lens _uiTableName (\s a -> s { _uiTableName = a })
+
+-- | An expression that defines one or more attributes to be updated, the
+-- action to be performed on them, and new value(s) for them. The following
+-- action values are available for UpdateExpression. SET - Adds one or more
+-- attributes and values to an item. If any of these attribute already
+-- exist, they are replaced by the new values. You can also use SET to add
+-- or subtract from an attribute that is of type Number. SET supports the
+-- following functions: if_not_exists (path, operand) - if the item does not
+-- contain an attribute at the specified path, then if_not_exists evaluates
+-- to operand; otherwise, it evaluates to path. You can use this function to
+-- avoid overwriting an attribute that may already be present in the item.
+-- list_append (operand, operand) - evaluates to a list with a new element
+-- added to it. You can append the new element to the start or the end of
+-- the list by reversing the order of the operands. These function names are
+-- case-sensitive. REMOVE - Removes one or more attributes from an item. ADD
+-- - Adds the specified value to the item, if the attribute does not already
+-- exist. If the attribute does exist, then the behavior of ADD depends on
+-- the data type of the attribute: If the existing attribute is a number,
+-- and if Value is also a number, then Value is mathematically added to the
+-- existing attribute. If Value is a negative number, then it is subtracted
+-- from the existing attribute. If the existing data type is a set and if
+-- Value is also a set, then Value is added to the existing set. For
+-- example, if the attribute value is the set [1,2], and the ADD action
+-- specified [3], then the final attribute value is [1,2,3]. An error occurs
+-- if an ADD action is specified for a set attribute and the attribute type
+-- specified does not match the existing set type. Both sets must have the
+-- same primitive data type. For example, if the existing data type is a set
+-- of strings, the Value must also be a set of strings. The ADD action only
+-- supports Number and set data types. In addition, ADD can only be used on
+-- top-level attributes, not nested attributes. DELETE - Deletes an element
+-- from a set. If a set of values is specified, then those values are
+-- subtracted from the old set. For example, if the attribute value was the
+-- set [a,b,c] and the DELETE action specifies [a,c], then the final
+-- attribute value is [b]. Specifying an empty set is an error. The DELETE
+-- action only supports Number and set data types. In addition, DELETE can
+-- only be used on top-level attributes, not nested attributes. You can have
+-- many actions in a single expression, such as the following: SET
+-- a=:value1, b=:value2 DELETE :value3, :value4, :value5 An expression can
+-- contain any of the following: Boolean functions: ATTRIBUTE_EXIST |
+-- CONTAINS | BEGINS_WITH Comparison operators: = | &#x3C;&#x3E; | &#x3C; |
+-- &#x3E; | &#x3C;= | &#x3E;= | BETWEEN | IN Logical operators: NOT | AND |
+-- OR.
+uiUpdateExpression :: Lens' UpdateItem (Maybe Text)
+uiUpdateExpression =
+    lens _uiUpdateExpression (\s a -> s { _uiUpdateExpression = a })
+
+data UpdateItemResponse = UpdateItemResponse
+    { _uirAttributes            :: Map Text AttributeValue
+    , _uirConsumedCapacity      :: Maybe ConsumedCapacity
+    , _uirItemCollectionMetrics :: Maybe ItemCollectionMetrics
+    } deriving (Eq, Show)
+
+-- | 'UpdateItemResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'uirAttributes' @::@ 'HashMap' 'Text' 'AttributeValue'
+--
+-- * 'uirConsumedCapacity' @::@ 'Maybe' 'ConsumedCapacity'
+--
+-- * 'uirItemCollectionMetrics' @::@ 'Maybe' 'ItemCollectionMetrics'
+--
+updateItemResponse :: UpdateItemResponse
+updateItemResponse = UpdateItemResponse
+    { _uirAttributes            = mempty
+    , _uirConsumedCapacity      = Nothing
+    , _uirItemCollectionMetrics = Nothing
+    }
+
+-- | A map of attribute values as they appeared before the UpdateItem
+-- operation. This map only appears if ReturnValues was specified as
+-- something other than NONE in the request. Each element represents one
+-- attribute.
+uirAttributes :: Lens' UpdateItemResponse (HashMap Text AttributeValue)
+uirAttributes = lens _uirAttributes (\s a -> s { _uirAttributes = a }) . _Map
+
+uirConsumedCapacity :: Lens' UpdateItemResponse (Maybe ConsumedCapacity)
+uirConsumedCapacity =
+    lens _uirConsumedCapacity (\s a -> s { _uirConsumedCapacity = a })
+
+uirItemCollectionMetrics :: Lens' UpdateItemResponse (Maybe ItemCollectionMetrics)
+uirItemCollectionMetrics =
+    lens _uirItemCollectionMetrics
+        (\s a -> s { _uirItemCollectionMetrics = a })
+
+instance ToPath UpdateItem where
+    toPath = const "/"
+
+instance ToQuery UpdateItem where
+    toQuery = const mempty
+
+instance ToHeaders UpdateItem
+
+instance ToJSON UpdateItem where
+    toJSON UpdateItem{..} = object
+        [ "TableName"                   .= _uiTableName
+        , "Key"                         .= _uiKey
+        , "AttributeUpdates"            .= _uiAttributeUpdates
+        , "Expected"                    .= _uiExpected
+        , "ConditionalOperator"         .= _uiConditionalOperator
+        , "ReturnValues"                .= _uiReturnValues
+        , "ReturnConsumedCapacity"      .= _uiReturnConsumedCapacity
+        , "ReturnItemCollectionMetrics" .= _uiReturnItemCollectionMetrics
+        , "UpdateExpression"            .= _uiUpdateExpression
+        , "ConditionExpression"         .= _uiConditionExpression
+        , "ExpressionAttributeNames"    .= _uiExpressionAttributeNames
+        , "ExpressionAttributeValues"   .= _uiExpressionAttributeValues
+        ]
+
+instance AWSRequest UpdateItem where
+    type Sv UpdateItem = DynamoDB
+    type Rs UpdateItem = UpdateItemResponse
+
+    request  = post "UpdateItem"
+    response = jsonResponse
+
+instance FromJSON UpdateItemResponse where
+    parseJSON = withObject "UpdateItemResponse" $ \o -> UpdateItemResponse
+        <$> o .:  "Attributes"
+        <*> o .:? "ConsumedCapacity"
+        <*> o .:? "ItemCollectionMetrics"
diff --git a/gen/Network/AWS/DynamoDB/UpdateTable.hs b/gen/Network/AWS/DynamoDB/UpdateTable.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/DynamoDB/UpdateTable.hs
@@ -0,0 +1,145 @@
+{-# LANGUAGE DataKinds                   #-}
+{-# LANGUAGE DeriveGeneric               #-}
+{-# LANGUAGE FlexibleInstances           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
+{-# LANGUAGE LambdaCase                  #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE OverloadedStrings           #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE TypeFamilies                #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+
+-- Module      : Network.AWS.DynamoDB.UpdateTable
+-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
+-- License     : This Source Code Form is subject to the terms of
+--               the Mozilla Public License, v. 2.0.
+--               A copy of the MPL can be found in the LICENSE file or
+--               you can obtain it at http://mozilla.org/MPL/2.0/.
+-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+
+-- | Updates the provisioned throughput for the given table. Setting the
+-- throughput for a table helps you manage performance and is part of the
+-- provisioned throughput feature of DynamoDB. The provisioned throughput
+-- values can be upgraded or downgraded based on the maximums and minimums
+-- listed in the Limits section in the Amazon DynamoDB Developer Guide. The
+-- table must be in the ACTIVE state for this operation to succeed.
+-- UpdateTable is an asynchronous operation; while executing the operation,
+-- the table is in the UPDATING state. While the table is in the UPDATING
+-- state, the table still has the provisioned throughput from before the call.
+-- The new provisioned throughput setting is in effect only when the table
+-- returns to the ACTIVE state after the UpdateTable operation. You cannot
+-- add, modify or delete indexes using UpdateTable. Indexes can only be
+-- defined at table creation time.
+--
+-- <http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTable.html>
+module Network.AWS.DynamoDB.UpdateTable
+    (
+    -- * Request
+      UpdateTable
+    -- ** Request constructor
+    , updateTable
+    -- ** Request lenses
+    , utGlobalSecondaryIndexUpdates
+    , utProvisionedThroughput
+    , utTableName
+
+    -- * Response
+    , UpdateTableResponse
+    -- ** Response constructor
+    , updateTableResponse
+    -- ** Response lenses
+    , utrTableDescription
+    ) where
+
+import Network.AWS.Prelude
+import Network.AWS.Request.JSON
+import Network.AWS.DynamoDB.Types
+import qualified GHC.Exts
+
+data UpdateTable = UpdateTable
+    { _utGlobalSecondaryIndexUpdates :: List "GlobalSecondaryIndexUpdates" GlobalSecondaryIndexUpdate
+    , _utProvisionedThroughput       :: Maybe ProvisionedThroughput
+    , _utTableName                   :: Text
+    } deriving (Eq, Show)
+
+-- | 'UpdateTable' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'utGlobalSecondaryIndexUpdates' @::@ ['GlobalSecondaryIndexUpdate']
+--
+-- * 'utProvisionedThroughput' @::@ 'Maybe' 'ProvisionedThroughput'
+--
+-- * 'utTableName' @::@ 'Text'
+--
+updateTable :: Text -- ^ 'utTableName'
+            -> UpdateTable
+updateTable p1 = UpdateTable
+    { _utTableName                   = p1
+    , _utProvisionedThroughput       = Nothing
+    , _utGlobalSecondaryIndexUpdates = mempty
+    }
+
+-- | An array of one or more global secondary indexes on the table, together
+-- with provisioned throughput settings for each index.
+utGlobalSecondaryIndexUpdates :: Lens' UpdateTable [GlobalSecondaryIndexUpdate]
+utGlobalSecondaryIndexUpdates =
+    lens _utGlobalSecondaryIndexUpdates
+        (\s a -> s { _utGlobalSecondaryIndexUpdates = a })
+            . _List
+
+utProvisionedThroughput :: Lens' UpdateTable (Maybe ProvisionedThroughput)
+utProvisionedThroughput =
+    lens _utProvisionedThroughput (\s a -> s { _utProvisionedThroughput = a })
+
+-- | The name of the table to be updated.
+utTableName :: Lens' UpdateTable Text
+utTableName = lens _utTableName (\s a -> s { _utTableName = a })
+
+newtype UpdateTableResponse = UpdateTableResponse
+    { _utrTableDescription :: Maybe TableDescription
+    } deriving (Eq, Show)
+
+-- | 'UpdateTableResponse' constructor.
+--
+-- The fields accessible through corresponding lenses are:
+--
+-- * 'utrTableDescription' @::@ 'Maybe' 'TableDescription'
+--
+updateTableResponse :: UpdateTableResponse
+updateTableResponse = UpdateTableResponse
+    { _utrTableDescription = Nothing
+    }
+
+utrTableDescription :: Lens' UpdateTableResponse (Maybe TableDescription)
+utrTableDescription =
+    lens _utrTableDescription (\s a -> s { _utrTableDescription = a })
+
+instance ToPath UpdateTable where
+    toPath = const "/"
+
+instance ToQuery UpdateTable where
+    toQuery = const mempty
+
+instance ToHeaders UpdateTable
+
+instance ToJSON UpdateTable where
+    toJSON UpdateTable{..} = object
+        [ "TableName"                   .= _utTableName
+        , "ProvisionedThroughput"       .= _utProvisionedThroughput
+        , "GlobalSecondaryIndexUpdates" .= _utGlobalSecondaryIndexUpdates
+        ]
+
+instance AWSRequest UpdateTable where
+    type Sv UpdateTable = DynamoDB
+    type Rs UpdateTable = UpdateTableResponse
+
+    request  = post "UpdateTable"
+    response = jsonResponse
+
+instance FromJSON UpdateTableResponse where
+    parseJSON = withObject "UpdateTableResponse" $ \o -> UpdateTableResponse
+        <$> o .:? "TableDescription"
