diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -83,10 +83,20 @@
   You can test the function and see the invocation results with `sls invoke
   myfunc`.
 
+  To invoke the function locally, use `sls invoke local -f myfunc`.
+
+### API Gateway
+
+This plugin supports handling API Gateway requests. Declare the HTTP events
+normally in `serverless.yml` and use
+[AWSLambda.Events.APIGateway](https://hackage.haskell.org/package/serverless-haskell/docs/AWSLambda-Events-APIGateway.html)
+in the handler to process them.
+
+[Serverless Offline] can be used for local testing of API Gateway requests.
+
 ### Notes
 
 * `sls deploy function` is [not supported yet](https://github.com/seek-oss/serverless-haskell/issues/20).
-* `sls invoke local` is [not supported yet](https://github.com/seek-oss/serverless-haskell/issues/32).
 * Only AWS Lambda is supported at the moment. Other cloud providers would
   require different JavaScript wrappers to be implemented.
 
@@ -128,4 +138,5 @@
 [jq]: https://stedolan.github.io/jq/
 [NPM]: https://www.npmjs.com/
 [Serverless]: https://serverless.com/framework/
+[Serverless Offline]: https://github.com/dherault/serverless-offline
 [Stack]: https://haskellstack.org
diff --git a/serverless-haskell.cabal b/serverless-haskell.cabal
--- a/serverless-haskell.cabal
+++ b/serverless-haskell.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: a288b7dc8892f8e7cdb3d9e4d980ac5efaf104fe9c7a57a274c93d42991a2145
+-- hash: 0fa49464ad722f9e904826775d750cd559324657f0fb63fff4212c4e818e7ba8
 
 name:           serverless-haskell
-version:        0.6.0
+version:        0.6.1
 synopsis:       Deploying Haskell code onto AWS Lambda using Serverless
 description:    Utilities to help process the events from AWS Lambda when deployed with the serverless-haskell plugin.
 category:       AWS, Cloud, Network
diff --git a/src/AWSLambda.hs b/src/AWSLambda.hs
--- a/src/AWSLambda.hs
+++ b/src/AWSLambda.hs
@@ -1,5 +1,5 @@
 {-|
-Module      : AWSLambda.Handler
+Module      : AWSLambda
 Stability   : experimental
 Portability : POSIX
 
@@ -44,6 +44,17 @@
 
   You can test the function and see the invocation results with @sls invoke
   myfunc@.
+
+  To invoke the function locally, use @sls invoke local -f myfunc@.
+
+= API Gateway
+
+This plugin supports handling API Gateway requests. Declare the HTTP events
+normally in @serverless.yml@ and use 'AWSLambda.Events.APIGateway' in the
+handler to process them.
+
+<https://github.com/dherault/serverless-offline Serverless Offline> can be used
+for local testing of API Gateway requests.
 
 = Additional features
 
diff --git a/src/AWSLambda/Events/APIGateway.hs b/src/AWSLambda/Events/APIGateway.hs
--- a/src/AWSLambda/Events/APIGateway.hs
+++ b/src/AWSLambda/Events/APIGateway.hs
@@ -8,6 +8,19 @@
 Description: Types for APIGateway Lambda requests and responses
 
 Based on https://github.com/aws/aws-lambda-dotnet/tree/master/Libraries/src/Amazon.Lambda.APIGatewayEvents
+
+To enable processing of API Gateway events, use the @events@ key in
+@serverless.yml@ as usual:
+
+> functions:
+>   myapifunc:
+>     handler: mypackage.mypackage-exe
+>     events:
+>       - http:
+>           path: hello/{name}
+>           method: get
+
+Then use 'apiGatewayMain' in the handler to process the requests.
 -}
 module AWSLambda.Events.APIGateway where
 
@@ -200,36 +213,36 @@
 responseBodyBinary :: Setter' (APIGatewayProxyResponse Base64) (Maybe ByteString)
 responseBodyBinary = responseBody . mapping _Base64
 
--- | Process incoming events from @serverless-haskell@ using a provided
--- function.
---
--- This is a specialisation of lambdaMain for API Gateway.
---
--- The handler receives the input event given to the AWS Lambda function, and
--- its return value is returned from the function.
---
--- This is intended to be used as @main@, for example:
---
--- > import AWSLambda.Events.APIGateway
--- > import Control.Lens
--- > import Data.Aeson
--- > import Data.Aeson.Embedded
--- >
--- > main = apiGatewayMain handler
--- >
--- > handler :: APIGatewayProxyRequest (Embedded Value) -> IO (APIGatewayProxyResponse (Embedded [Int]))
--- > handler request = do
--- >   putStrLn "This should go to logs"
--- >   print $ request ^. requestBody
--- >   pure $ responseOK & responseBodyEmbedded ?~ [1, 2, 3]
---
--- The type parameters @reqBody@ and @resBody@ represent the types of request and response body, respectively.
--- The @FromText@ and @ToText@ contraints are required because these values come from string fields
--- in the request and response JSON objects.
--- To get direct access to the body string, use @Text@ as the parameter type.
--- To treat the body as a stringified embedded JSON value, use @Embedded a@, where @a@ has the
--- appropriate @FromJSON@ or @ToJSON@ instances.
--- To treat the body as base 64 encoded binary use @Base64@.
+{-| Process incoming events from @serverless-haskell@ using a provided function.
+
+This is a specialisation of 'lambdaMain' for API Gateway.
+
+The handler receives the input event given to the AWS Lambda function, and
+its return value is returned from the function.
+
+This is intended to be used as @main@, for example:
+
+> import AWSLambda.Events.APIGateway
+> import Control.Lens
+> import Data.Aeson
+> import Data.Aeson.Embedded
+>
+> main = apiGatewayMain handler
+>
+> handler :: APIGatewayProxyRequest (Embedded Value) -> IO (APIGatewayProxyResponse (Embedded [Int]))
+> handler request = do
+>   putStrLn "This should go to logs"
+>   print $ request ^. requestBody
+>   pure $ responseOK & responseBodyEmbedded ?~ [1, 2, 3]
+
+The type parameters @reqBody@ and @resBody@ represent the types of request and response body, respectively.
+The @FromText@ and @ToText@ contraints are required because these values come from string fields
+in the request and response JSON objects.
+To get direct access to the body string, use @Text@ as the parameter type.
+To treat the body as a stringified embedded JSON value, use @Embedded a@, where @a@ has the
+appropriate @FromJSON@ or @ToJSON@ instances.
+To treat the body as base 64 encoded binary use @Base64@.
+-}
 apiGatewayMain
   :: (FromText reqBody, ToText resBody)
   => (APIGatewayProxyRequest reqBody -> IO (APIGatewayProxyResponse resBody)) -- ^ Function to process the event
diff --git a/src/AWSLambda/Handler.hs b/src/AWSLambda/Handler.hs
--- a/src/AWSLambda/Handler.hs
+++ b/src/AWSLambda/Handler.hs
@@ -5,11 +5,13 @@
 
 Entry point for AWS Lambda handlers deployed with @serverless-haskell@ plugin.
 -}
+{-# LANGUAGE TypeApplications #-}
+
 module AWSLambda.Handler
   ( lambdaMain
   ) where
 
-import Control.Exception (bracket)
+import Control.Exception (bracket, try)
 
 import qualified Data.Aeson as Aeson
 import qualified Data.Aeson.Text as Aeson
@@ -18,10 +20,11 @@
 
 import qualified Data.Text.Lazy.IO as Text
 
-import GHC.IO.Handle (Handle, hClose)
+import GHC.IO.Handle
+       (BufferMode(..), Handle, hClose, hSetBuffering)
 
-import System.Environment (lookupEnv)
 import System.IO (stdout)
+import System.Posix.Files (getFdStatus)
 import System.Posix.IO (fdToHandle)
 import System.Posix.Types (Fd(..))
 
@@ -88,15 +91,18 @@
         Text.hPutStrLn resultChannel $ Aeson.encodeToLazyText result
         pure ()
 
--- | Invoke an action with the handle to write the results to. On AWS Lambda,
--- use the channel opened by the JavaScript wrapper, otherwise use standard
--- output.
+-- | Invoke an action with the handle to write the results to. If called by the
+-- JavaScript wrapper, use the channel opened by it, otherwise use standard
+-- output. Also set line buffering on standard output for AWS Lambda so the logs
+-- are output in a timely manner.
 withResultChannel :: (Handle -> IO r) -> IO r
 withResultChannel act = do
-  lambdaFunctionName <- lookupEnv "AWS_LAMBDA_FUNCTION_NAME"
-  case lambdaFunctionName of
-    Just _ -> bracket (fdToHandle communicationFd) hClose act
-    Nothing -> act stdout
+  commStatus <- try @IOError $ getFdStatus communicationFd
+  case commStatus of
+    Right _ -> do
+      hSetBuffering stdout LineBuffering
+      bracket (fdToHandle communicationFd) hClose act
+    Left _ -> act stdout
 
 -- | File descriptor opened by the JavaScript wrapper to listen for the results
 communicationFd :: Fd
