diff --git a/amazonka-elastictranscoder.cabal b/amazonka-elastictranscoder.cabal
--- a/amazonka-elastictranscoder.cabal
+++ b/amazonka-elastictranscoder.cabal
@@ -1,5 +1,5 @@
 name:                  amazonka-elastictranscoder
-version:               0.0.7
+version:               0.0.8
 synopsis:              Amazon Elastic Transcoder SDK.
 homepage:              https://github.com/brendanhay/amazonka
 license:               OtherLicense
@@ -55,9 +55,10 @@
         , Network.AWS.ElasticTranscoder.UpdatePipeline
         , Network.AWS.ElasticTranscoder.UpdatePipelineNotifications
         , Network.AWS.ElasticTranscoder.UpdatePipelineStatus
+        , Network.AWS.ElasticTranscoder.Waiters
 
     other-modules:
 
     build-depends:
-          amazonka-core == 0.0.7.*
+          amazonka-core == 0.0.8.*
         , base          >= 4.7     && < 5
diff --git a/gen/Network/AWS/ElasticTranscoder.hs b/gen/Network/AWS/ElasticTranscoder.hs
--- a/gen/Network/AWS/ElasticTranscoder.hs
+++ b/gen/Network/AWS/ElasticTranscoder.hs
@@ -34,6 +34,7 @@
     , module Network.AWS.ElasticTranscoder.UpdatePipeline
     , module Network.AWS.ElasticTranscoder.UpdatePipelineNotifications
     , module Network.AWS.ElasticTranscoder.UpdatePipelineStatus
+    , module Network.AWS.ElasticTranscoder.Waiters
     ) where
 
 import Network.AWS.ElasticTranscoder.CancelJob
@@ -54,3 +55,4 @@
 import Network.AWS.ElasticTranscoder.UpdatePipeline
 import Network.AWS.ElasticTranscoder.UpdatePipelineNotifications
 import Network.AWS.ElasticTranscoder.UpdatePipelineStatus
+import Network.AWS.ElasticTranscoder.Waiters
diff --git a/gen/Network/AWS/ElasticTranscoder/ReadJob.hs b/gen/Network/AWS/ElasticTranscoder/ReadJob.hs
--- a/gen/Network/AWS/ElasticTranscoder/ReadJob.hs
+++ b/gen/Network/AWS/ElasticTranscoder/ReadJob.hs
@@ -68,22 +68,23 @@
 rjId = lens _rjId (\s a -> s { _rjId = a })
 
 newtype ReadJobResponse = ReadJobResponse
-    { _rjrJob :: Maybe Job'
+    { _rjrJob :: Job'
     } deriving (Eq, Show)
 
 -- | 'ReadJobResponse' constructor.
 --
 -- The fields accessible through corresponding lenses are:
 --
--- * 'rjrJob' @::@ 'Maybe' 'Job''
+-- * 'rjrJob' @::@ 'Job''
 --
-readJobResponse :: ReadJobResponse
-readJobResponse = ReadJobResponse
-    { _rjrJob = Nothing
+readJobResponse :: Job' -- ^ 'rjrJob'
+                -> ReadJobResponse
+readJobResponse p1 = ReadJobResponse
+    { _rjrJob = p1
     }
 
 -- | A section of the response body that provides information about the job.
-rjrJob :: Lens' ReadJobResponse (Maybe Job')
+rjrJob :: Lens' ReadJobResponse Job'
 rjrJob = lens _rjrJob (\s a -> s { _rjrJob = a })
 
 instance ToPath ReadJob where
@@ -109,4 +110,4 @@
 
 instance FromJSON ReadJobResponse where
     parseJSON = withObject "ReadJobResponse" $ \o -> ReadJobResponse
-        <$> o .:? "Job"
+        <$> o .:  "Job"
diff --git a/gen/Network/AWS/ElasticTranscoder/Types.hs b/gen/Network/AWS/ElasticTranscoder/Types.hs
--- a/gen/Network/AWS/ElasticTranscoder/Types.hs
+++ b/gen/Network/AWS/ElasticTranscoder/Types.hs
@@ -7,6 +7,7 @@
 {-# LANGUAGE OverloadedStrings           #-}
 {-# LANGUAGE RecordWildCards             #-}
 {-# LANGUAGE TypeFamilies                #-}
+{-# LANGUAGE ViewPatterns                #-}
 
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
 
@@ -281,8 +282,6 @@
     , jiResolution
     ) where
 
-import Data.Char (isUpper)
-import Network.AWS.Error
 import Network.AWS.Prelude
 import Network.AWS.Signing
 import qualified GHC.Exts
@@ -294,16 +293,41 @@
     type Sg ElasticTranscoder = V4
     type Er ElasticTranscoder = JSONError
 
-    service = Service
-        { _svcAbbrev       = "ElasticTranscoder"
-        , _svcPrefix       = "elastictranscoder"
-        , _svcVersion      = "2012-09-25"
-        , _svcTargetPrefix = Nothing
-        , _svcJSONVersion  = Nothing
-        }
+    service = service'
+      where
+        service' :: Service ElasticTranscoder
+        service' = Service
+            { _svcAbbrev       = "ElasticTranscoder"
+            , _svcPrefix       = "elastictranscoder"
+            , _svcVersion      = "2012-09-25"
+            , _svcTargetPrefix = Nothing
+            , _svcJSONVersion  = Nothing
+            , _svcHandle       = handle
+            , _svcRetry        = retry
+            }
 
-    handle = jsonError statusSuccess
+        handle :: Status
+               -> Maybe (LazyByteString -> ServiceError JSONError)
+        handle = jsonError statusSuccess service'
 
+        retry :: Retry ElasticTranscoder
+        retry = Exponential
+            { _retryBase     = 0.05
+            , _retryGrowth   = 2
+            , _retryAttempts = 5
+            , _retryCheck    = check
+            }
+
+        check :: Status
+              -> JSONError
+              -> Bool
+        check (statusCode -> s) (awsErrorCode -> e)
+            | s == 400 && "ThrottlingException" == e = True -- Throttling
+            | s == 500  = True -- General Server Error
+            | s == 509  = True -- Limit Exceeded
+            | s == 503  = True -- Service Unavailable
+            | otherwise = False
+
 data PipelineOutputConfig = PipelineOutputConfig
     { _pocBucket       :: Maybe Text
     , _pocPermissions  :: List "Permissions" Permission
@@ -892,14 +916,14 @@
 
 data Job' = Job'
     { _jArn             :: Maybe Text
-    , _jId              :: Maybe Text
-    , _jInput           :: Maybe JobInput
+    , _jId              :: Text
+    , _jInput           :: JobInput
     , _jOutput          :: Maybe JobOutput
-    , _jOutputKeyPrefix :: Maybe Text
+    , _jOutputKeyPrefix :: Text
     , _jOutputs         :: List "Outputs" JobOutput
-    , _jPipelineId      :: Maybe Text
+    , _jPipelineId      :: Text
     , _jPlaylists       :: List "Playlists" Playlist
-    , _jStatus          :: Maybe Text
+    , _jStatus          :: Text
     } deriving (Eq, Show)
 
 -- | 'Job'' constructor.
@@ -908,33 +932,38 @@
 --
 -- * 'jArn' @::@ 'Maybe' 'Text'
 --
--- * 'jId' @::@ 'Maybe' 'Text'
+-- * 'jId' @::@ 'Text'
 --
--- * 'jInput' @::@ 'Maybe' 'JobInput'
+-- * 'jInput' @::@ 'JobInput'
 --
 -- * 'jOutput' @::@ 'Maybe' 'JobOutput'
 --
--- * 'jOutputKeyPrefix' @::@ 'Maybe' 'Text'
+-- * 'jOutputKeyPrefix' @::@ 'Text'
 --
 -- * 'jOutputs' @::@ ['JobOutput']
 --
--- * 'jPipelineId' @::@ 'Maybe' 'Text'
+-- * 'jPipelineId' @::@ 'Text'
 --
 -- * 'jPlaylists' @::@ ['Playlist']
 --
--- * 'jStatus' @::@ 'Maybe' 'Text'
+-- * 'jStatus' @::@ 'Text'
 --
-job :: Job'
-job = Job'
-    { _jId              = Nothing
+job :: Text -- ^ 'jId'
+    -> Text -- ^ 'jPipelineId'
+    -> JobInput -- ^ 'jInput'
+    -> Text -- ^ 'jOutputKeyPrefix'
+    -> Text -- ^ 'jStatus'
+    -> Job'
+job p1 p2 p3 p4 p5 = Job'
+    { _jId              = p1
+    , _jPipelineId      = p2
+    , _jInput           = p3
+    , _jOutputKeyPrefix = p4
+    , _jStatus          = p5
     , _jArn             = Nothing
-    , _jPipelineId      = Nothing
-    , _jInput           = Nothing
     , _jOutput          = Nothing
     , _jOutputs         = mempty
-    , _jOutputKeyPrefix = Nothing
     , _jPlaylists       = mempty
-    , _jStatus          = Nothing
     }
 
 -- | The Amazon Resource Name (ARN) for the job.
@@ -943,12 +972,12 @@
 
 -- | The identifier that Elastic Transcoder assigned to the job. You use this
 -- value to get settings for the job or to delete the job.
-jId :: Lens' Job' (Maybe Text)
+jId :: Lens' Job' Text
 jId = lens _jId (\s a -> s { _jId = a })
 
 -- | A section of the request or response body that provides information about
 -- the file that is being transcoded.
-jInput :: Lens' Job' (Maybe JobInput)
+jInput :: Lens' Job' JobInput
 jInput = lens _jInput (\s a -> s { _jInput = a })
 
 -- | If you specified one output for a job, information about that output. If you
@@ -965,7 +994,7 @@
 -- of all files that this job creates, including output files, thumbnails, and
 -- playlists. We recommend that you add a / or some other delimiter to the end
 -- of the 'OutputKeyPrefix'.
-jOutputKeyPrefix :: Lens' Job' (Maybe Text)
+jOutputKeyPrefix :: Lens' Job' Text
 jOutputKeyPrefix = lens _jOutputKeyPrefix (\s a -> s { _jOutputKeyPrefix = a })
 
 -- | Information about the output files. We recommend that you use the 'Outputs'
@@ -982,7 +1011,7 @@
 -- transcoding. The pipeline determines several settings, including the Amazon
 -- S3 bucket from which Elastic Transcoder gets the files to transcode and the
 -- bucket into which Elastic Transcoder puts the transcoded files.
-jPipelineId :: Lens' Job' (Maybe Text)
+jPipelineId :: Lens' Job' Text
 jPipelineId = lens _jPipelineId (\s a -> s { _jPipelineId = a })
 
 -- | Outputs in Fragmented MP4 or MPEG-TS format only.If you specify a preset in 'PresetId' for which the value of 'Container' is fmp4 (Fragmented MP4) or ts (MPEG-TS), 'Playlists' contains information about the master playlists that you want Elastic
@@ -993,20 +1022,20 @@
 jPlaylists = lens _jPlaylists (\s a -> s { _jPlaylists = a }) . _List
 
 -- | The status of the job: 'Submitted', 'Progressing', 'Complete', 'Canceled', or 'Error'.
-jStatus :: Lens' Job' (Maybe Text)
+jStatus :: Lens' Job' Text
 jStatus = lens _jStatus (\s a -> s { _jStatus = a })
 
 instance FromJSON Job' where
     parseJSON = withObject "Job'" $ \o -> Job'
         <$> o .:? "Arn"
-        <*> o .:? "Id"
-        <*> o .:? "Input"
+        <*> o .:  "Id"
+        <*> o .:  "Input"
         <*> o .:? "Output"
-        <*> o .:? "OutputKeyPrefix"
+        <*> o .:  "OutputKeyPrefix"
         <*> o .:? "Outputs" .!= mempty
-        <*> o .:? "PipelineId"
+        <*> o .:  "PipelineId"
         <*> o .:? "Playlists" .!= mempty
-        <*> o .:? "Status"
+        <*> o .:  "Status"
 
 instance ToJSON Job' where
     toJSON Job'{..} = object
diff --git a/gen/Network/AWS/ElasticTranscoder/Waiters.hs b/gen/Network/AWS/ElasticTranscoder/Waiters.hs
new file mode 100644
--- /dev/null
+++ b/gen/Network/AWS/ElasticTranscoder/Waiters.hs
@@ -0,0 +1,35 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TypeFamilies      #-}
+
+-- Module      : Network.AWS.ElasticTranscoder.Waiters
+-- 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)
+--
+-- Derived from AWS service descriptions, licensed under Apache 2.0.
+
+module Network.AWS.ElasticTranscoder.Waiters where
+
+import Network.AWS.ElasticTranscoder.ReadJob
+import Network.AWS.ElasticTranscoder.Types
+import Network.AWS.Waiters
+
+jobComplete :: Wait ReadJob
+jobComplete = Wait
+    { _waitName      = "JobComplete"
+    , _waitAttempts  = 120
+    , _waitDelay     = 30
+    , _waitAcceptors =
+        [ matchAll "Complete" AcceptSuccess
+            (rjrJob . jStatus)
+        , matchAll "Canceled" AcceptFailure
+            (rjrJob . jStatus)
+        , matchAll "Error" AcceptFailure
+            (rjrJob . jStatus)
+        ]
+    }
