diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,10 @@
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## 0.7.2.1 - 2022-12-29
+
+Maintenance and tooling update.
+
 ## [0.7.2.0] - 2022-03-15
 
 ### Added
diff --git a/hercules-ci-api.cabal b/hercules-ci-api.cabal
--- a/hercules-ci-api.cabal
+++ b/hercules-ci-api.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.12
 name:               hercules-ci-api
-version:            0.7.2.0
+version:            0.7.2.1
 synopsis:           Hercules CI API definition with Servant
 homepage:           https://github.com/hercules-ci/hercules-ci-agent#readme
 bug-reports:        https://github.com/hercules-ci/hercules-ci-agent/issues
diff --git a/src/Hercules/API.hs b/src/Hercules/API.hs
--- a/src/Hercules/API.hs
+++ b/src/Hercules/API.hs
@@ -47,7 +47,6 @@
 import Hercules.API.Servant (useApi)
 import Hercules.API.State (StateAPI)
 import Servant.API
-import Servant.API.Generic
 import Servant.Auth
 import Servant.Auth.Swagger ()
 import Servant.Swagger
@@ -96,7 +95,7 @@
 type API auth =
   HerculesServantAPI auth
     :<|> "api"
-    :> SwaggerSchemaUI "v1" "swagger.json"
+      :> SwaggerSchemaUI "v1" "swagger.json"
 
 api :: Proxy (API auth)
 api = Proxy
@@ -106,13 +105,13 @@
   toSwagger (servantClientApi @(Auth '[JWT] ()))
     & info
       . title
-    .~ "Hercules CI API"
+      .~ "Hercules CI API"
     & info
       . version
-    .~ "v1"
+      .~ "v1"
     & info
       . description
-    ?~ "You have reached the Hercules Continuous Integration Application Programming Interface. This user interface provides human friendly access to the various endpoints. To get started with Hercules CI, see hercules-ci.com. Happy building! —the Hercules team"
+      ?~ "You have reached the Hercules Continuous Integration Application Programming Interface. This user interface provides human friendly access to the various endpoints. To get started with Hercules CI, see hercules-ci.com. Happy building! —the Hercules team"
 
 -- | 'Control.Monad.void' specialised to 'NoContent' to soothe the
 -- compiler that rightfully warns about throwing away a do notation
diff --git a/src/Hercules/API/Accounts.hs b/src/Hercules/API/Accounts.hs
--- a/src/Hercules/API/Accounts.hs
+++ b/src/Hercules/API/Accounts.hs
@@ -20,30 +20,33 @@
   ( SourceHostingSite,
   )
 import Servant.API
-import Servant.API.Generic
 import Servant.Auth ()
 
 data AccountResourceGroup auth f = AccountResourceGroup
   { get ::
-      f :- Summary ("Get the account.")
-        :> auth
-        :> Get '[JSON] Account,
+      f
+        :- Summary ("Get the account.")
+          :> auth
+          :> Get '[JSON] Account,
     getSettings ::
-      f :- Summary ("Get the account settings.")
-        :> "settings"
-        :> auth
-        :> Get '[JSON] AccountSettings,
+      f
+        :- Summary ("Get the account settings.")
+          :> "settings"
+          :> auth
+          :> Get '[JSON] AccountSettings,
     patchSettings ::
-      f :- Summary ("Update the account settings.")
-        :> "settings"
-        :> ReqBody '[JSON] AccountSettingsPatch
-        :> auth
-        :> Patch '[JSON] AccountSettings,
+      f
+        :- Summary ("Update the account settings.")
+          :> "settings"
+          :> ReqBody '[JSON] AccountSettingsPatch
+          :> auth
+          :> Patch '[JSON] AccountSettings,
     postDisableAllProjects ::
-      f :- Summary ("Disable all projects in the account.")
-        :> "disable-all-projects"
-        :> auth
-        :> Post '[JSON] Int
+      f
+        :- Summary ("Disable all projects in the account.")
+          :> "disable-all-projects"
+          :> auth
+          :> Post '[JSON] Int
   }
   deriving (Generic)
 
@@ -58,22 +61,22 @@
     accountByAuthGetNotificationSettings ::
       f
         :- Summary "Retrieve notification settings"
-        :> "accounts"
-        :> "me"
-        :> "settings"
-        :> "notifications"
-        :> auth
-        :> Get '[JSON] NotificationSettings,
+          :> "accounts"
+          :> "me"
+          :> "settings"
+          :> "notifications"
+          :> auth
+          :> Get '[JSON] NotificationSettings,
     accountByAuthPatchNotificationSettings ::
       f
         :- Summary "Update notification settings"
-        :> "accounts"
-        :> "me"
-        :> "settings"
-        :> "notifications"
-        :> ReqBody '[JSON] NotificationSettingsPatch
-        :> auth
-        :> Patch '[JSON] NotificationSettings,
+          :> "accounts"
+          :> "me"
+          :> "settings"
+          :> "notifications"
+          :> ReqBody '[JSON] NotificationSettingsPatch
+          :> auth
+          :> Patch '[JSON] NotificationSettings,
     accountById ::
       f
         :- Substitute
@@ -90,72 +93,80 @@
              )
              (ToServantApi (AccountResourceGroup auth)),
     findAccounts ::
-      f :- Summary "Accounts that the authenticated user owns, admins or collaborates with."
-        :> "accounts"
-        :> QueryParam "site" (Name SourceHostingSite)
-        :> QueryParam "name" (Name Account)
-        :> auth
-        :> Get '[JSON] [Account],
+      f
+        :- Summary "Accounts that the authenticated user owns, admins or collaborates with."
+          :> "accounts"
+          :> QueryParam "site" (Name SourceHostingSite)
+          :> QueryParam "name" (Name Account)
+          :> auth
+          :> Get '[JSON] [Account],
     postCLIAuthorizationRequest ::
-      f :- Summary "Create a request to authorize the CLI."
-        :> "auth"
-        :> "cli"
-        :> "authorization"
-        :> "request"
-        :> ReqBody '[JSON] CLIAuthorizationRequestCreate
-        :> Post '[JSON] CLIAuthorizationRequestCreateResponse,
+      f
+        :- Summary "Create a request to authorize the CLI."
+          :> "auth"
+          :> "cli"
+          :> "authorization"
+          :> "request"
+          :> ReqBody '[JSON] CLIAuthorizationRequestCreate
+          :> Post '[JSON] CLIAuthorizationRequestCreateResponse,
     getCLIAuthorizationRequestStatus ::
-      f :- Summary "Check the request status"
-        :> "auth"
-        :> "cli"
-        :> "authorization"
-        :> "request"
-        :> "status"
-        :> Capture "temporaryToken" Text
-        :> Get '[JSON] CLIAuthorizationRequestStatus,
+      f
+        :- Summary "Check the request status"
+          :> "auth"
+          :> "cli"
+          :> "authorization"
+          :> "request"
+          :> "status"
+          :> Capture "temporaryToken" Text
+          :> Get '[JSON] CLIAuthorizationRequestStatus,
     getCLIAuthorizationRequest ::
-      f :- Summary "Retrieve the request"
-        :> "auth"
-        :> "cli"
-        :> "authorization"
-        :> "request"
-        :> Capture "browserToken" Text
-        :> auth
-        :> Get '[JSON] CLIAuthorizationRequest,
+      f
+        :- Summary "Retrieve the request"
+          :> "auth"
+          :> "cli"
+          :> "authorization"
+          :> "request"
+          :> Capture "browserToken" Text
+          :> auth
+          :> Get '[JSON] CLIAuthorizationRequest,
     confirmCLIAuthorizationRequest ::
-      f :- Summary "Retrieve the request"
-        :> "auth"
-        :> "cli"
-        :> "authorization"
-        :> "request"
-        :> Capture "browserToken" Text
-        :> "confirm"
-        :> auth
-        :> Post '[JSON] NoContent,
+      f
+        :- Summary "Retrieve the request"
+          :> "auth"
+          :> "cli"
+          :> "authorization"
+          :> "request"
+          :> Capture "browserToken" Text
+          :> "confirm"
+          :> auth
+          :> Post '[JSON] NoContent,
     getCLITokens ::
-      f :- Summary "List the CLI tokens associated with the current account."
-        :> "auth"
-        :> "cli"
-        :> "tokens"
-        :> auth
-        :> Get '[JSON] CLITokensResponse,
+      f
+        :- Summary "List the CLI tokens associated with the current account."
+          :> "auth"
+          :> "cli"
+          :> "tokens"
+          :> auth
+          :> Get '[JSON] CLITokensResponse,
     revokeCLIToken ::
-      f :- Summary "Permanently disallow the use of a CLI token."
-        :> "auth"
-        :> "cli"
-        :> "tokens"
-        :> Capture "cliTokenId" (Id "CLIToken")
-        :> "revoke"
-        :> auth
-        :> Post '[JSON] NoContent,
+      f
+        :- Summary "Permanently disallow the use of a CLI token."
+          :> "auth"
+          :> "cli"
+          :> "tokens"
+          :> Capture "cliTokenId" (Id "CLIToken")
+          :> "revoke"
+          :> auth
+          :> Post '[JSON] NoContent,
     installationStatus ::
-      f :- Summary "Retrieve installation status after redirect from external source site settings."
-        :> "sites"
-        :> Capture "siteId" (Id SourceHostingSite)
-        :> "installation"
-        :> Capture "installationId" Int
-        :> "status"
-        :> auth
-        :> Get '[JSON] AccountInstallationStatus
+      f
+        :- Summary "Retrieve installation status after redirect from external source site settings."
+          :> "sites"
+          :> Capture "siteId" (Id SourceHostingSite)
+          :> "installation"
+          :> Capture "installationId" Int
+          :> "status"
+          :> auth
+          :> Get '[JSON] AccountInstallationStatus
   }
   deriving (Generic)
diff --git a/src/Hercules/API/Agents.hs b/src/Hercules/API/Agents.hs
--- a/src/Hercules/API/Agents.hs
+++ b/src/Hercules/API/Agents.hs
@@ -18,38 +18,41 @@
   )
 import Hercules.API.Prelude
 import Servant.API
-import Servant.API.Generic
 
 data AgentsAPI auth f = AgentsAPI
   { clusterJoinTokensByAccount ::
-      f :- Summary "List all cluster join tokens in an account."
-        :> "accounts"
-        :> Capture' '[Required, Strict] "accountId" (Id Account)
-        :> "clusterJoinTokens"
-        :> auth
-        :> Get '[JSON] [ClusterJoinToken],
+      f
+        :- Summary "List all cluster join tokens in an account."
+          :> "accounts"
+          :> Capture' '[Required, Strict] "accountId" (Id Account)
+          :> "clusterJoinTokens"
+          :> auth
+          :> Get '[JSON] [ClusterJoinToken],
     clusterJoinTokenCreate ::
-      f :- Summary "Generate a new cluster join token for agents to be added to this account."
-        :> "accounts"
-        :> Capture' '[Required, Strict] "accountId" (Id Account)
-        :> "clusterJoinTokens"
-        :> ReqBody '[JSON] CreateClusterJoinToken
-        :> auth
-        :> Post '[JSON] FullClusterJoinToken,
+      f
+        :- Summary "Generate a new cluster join token for agents to be added to this account."
+          :> "accounts"
+          :> Capture' '[Required, Strict] "accountId" (Id Account)
+          :> "clusterJoinTokens"
+          :> ReqBody '[JSON] CreateClusterJoinToken
+          :> auth
+          :> Post '[JSON] FullClusterJoinToken,
     clusterJoinTokenDelete ::
-      f :- Summary "Delete an cluster join token in the account. No new agents will be able to join this account with the specified token."
-        :> "accounts"
-        :> Capture' '[Required, Strict] "accountId" (Id Account)
-        :> "clusterJoinTokens"
-        :> Capture' '[Required, Strict] "clusterJoinTokenId" (Id ClusterJoinToken)
-        :> auth
-        :> Delete '[JSON] NoContent,
+      f
+        :- Summary "Delete an cluster join token in the account. No new agents will be able to join this account with the specified token."
+          :> "accounts"
+          :> Capture' '[Required, Strict] "accountId" (Id Account)
+          :> "clusterJoinTokens"
+          :> Capture' '[Required, Strict] "clusterJoinTokenId" (Id ClusterJoinToken)
+          :> auth
+          :> Delete '[JSON] NoContent,
     agentSessionsByAccount ::
-      f :- Summary "Show the agents sessions owned by the account."
-        :> "accounts"
-        :> Capture' '[Required, Strict] "accountId" (Id Account)
-        :> "agentSessions"
-        :> auth
-        :> Get '[JSON] [AgentSession]
+      f
+        :- Summary "Show the agents sessions owned by the account."
+          :> "accounts"
+          :> Capture' '[Required, Strict] "accountId" (Id Account)
+          :> "agentSessions"
+          :> auth
+          :> Get '[JSON] [AgentSession]
   }
   deriving (Generic)
diff --git a/src/Hercules/API/Auth.hs b/src/Hercules/API/Auth.hs
--- a/src/Hercules/API/Auth.hs
+++ b/src/Hercules/API/Auth.hs
@@ -5,22 +5,23 @@
 import Hercules.API.Prelude
 import Hercules.API.Servant.Status
 import Servant.API
-import Servant.API.Generic
 import Web.Cookie (SetCookie)
 
 -- | Endpoints for authentication
 data AuthAPI auth f = AuthAPI
   { initiateGitHubLogin ::
-      f :- "api"
-        :> "auth"
-        :> "github"
-        :> QueryParam' '[Optional, Strict] "redirect" Text
-        :> Get302 '[PlainText, JSON] '[],
+      f
+        :- "api"
+          :> "auth"
+          :> "github"
+          :> QueryParam' '[Optional, Strict] "redirect" Text
+          :> Get302 '[PlainText, JSON] '[],
     signOut ::
-      f :- "api"
-        :> "auth"
-        :> "sign-out"
-        :> auth
-        :> Post '[JSON] (Headers '[Header "Set-Cookie" SetCookie, Header "Set-Cookie" SetCookie] NoContent)
+      f
+        :- "api"
+          :> "auth"
+          :> "sign-out"
+          :> auth
+          :> Post '[JSON] (Headers '[Header "Set-Cookie" SetCookie, Header "Set-Cookie" SetCookie] NoContent)
   }
   deriving (Generic)
diff --git a/src/Hercules/API/Build.hs b/src/Hercules/API/Build.hs
--- a/src/Hercules/API/Build.hs
+++ b/src/Hercules/API/Build.hs
@@ -8,51 +8,54 @@
 import Hercules.API.Prelude
 import Hercules.API.Projects.Job (Job)
 import Servant.API
-import Servant.API.Generic
 
 data BuildAPI auth f = BuildAPI
   { restartDerivation ::
-      f :- Summary "Restart a derivation"
-        :> "accounts"
-        :> Capture "accountId" (Id Account)
-        :> "derivations"
-        :> Capture "derivationPath" Text
-        :> "retry"
-        :> auth
-        :> Post '[PlainText, JSON] NoContent,
+      f
+        :- Summary "Restart a derivation"
+          :> "accounts"
+          :> Capture "accountId" (Id Account)
+          :> "derivations"
+          :> Capture "derivationPath" Text
+          :> "retry"
+          :> auth
+          :> Post '[PlainText, JSON] NoContent,
     readDerivationLogText ::
-      f :- Summary "Read a derivation build log"
-        :> Description "This interface may change."
-        :> "accounts"
-        :> Capture "accountId" (Id Account)
-        :> "derivations"
-        :> Capture "derivationPath" Text
-        :> "log"
-        :> QueryParam "logId" (Id "log")
-        :> auth
-        :> Get '[PlainText, JSON] Text, -- NB: We use JSON only to be able to generate elm api
-        -- FIXME: bytes?
+      f
+        :- Summary "Read a derivation build log"
+          :> Description "This interface may change."
+          :> "accounts"
+          :> Capture "accountId" (Id Account)
+          :> "derivations"
+          :> Capture "derivationPath" Text
+          :> "log"
+          :> QueryParam "logId" (Id "log")
+          :> auth
+          :> Get '[PlainText, JSON] Text, -- NB: We use JSON only to be able to generate elm api
+          -- FIXME: bytes?
     getLog ::
-      f :- Summary "Read all recorded log entries"
-        :> "accounts"
-        :> Capture "accountId" (Id Account)
-        :> "derivations"
-        :> Capture "derivationPath" Text
-        :> "log"
-        :> "lines"
-        :> QueryParam' '[Required] "logId" (Id "log")
-        :> QueryParam' '[Optional] "iMin" Int
-        :> auth
-        :> Get '[JSON] Log,
+      f
+        :- Summary "Read all recorded log entries"
+          :> "accounts"
+          :> Capture "accountId" (Id Account)
+          :> "derivations"
+          :> Capture "derivationPath" Text
+          :> "log"
+          :> "lines"
+          :> QueryParam' '[Required] "logId" (Id "log")
+          :> QueryParam' '[Optional] "iMin" Int
+          :> auth
+          :> Get '[JSON] Log,
     getDerivationInfo ::
-      f :- Summary "Get information about a derivation."
-        :> Description "Optionally, a job id can be specified to provide context."
-        :> "accounts"
-        :> Capture "accountId" (Id Account)
-        :> "derivations"
-        :> Capture "derivationPath" Text
-        :> QueryParam' '[Optional, Strict] "via-job" (Id Job)
-        :> auth
-        :> Get '[JSON] DerivationInfo
+      f
+        :- Summary "Get information about a derivation."
+          :> Description "Optionally, a job id can be specified to provide context."
+          :> "accounts"
+          :> Capture "accountId" (Id Account)
+          :> "derivations"
+          :> Capture "derivationPath" Text
+          :> QueryParam' '[Optional, Strict] "via-job" (Id Job)
+          :> auth
+          :> Get '[JSON] DerivationInfo
   }
   deriving (Generic)
diff --git a/src/Hercules/API/Effects.hs b/src/Hercules/API/Effects.hs
--- a/src/Hercules/API/Effects.hs
+++ b/src/Hercules/API/Effects.hs
@@ -7,38 +7,40 @@
 import Hercules.API.Effects.EffectInfo
 import Hercules.API.Prelude
 import Hercules.API.Projects.Job (Job)
-import Servant.API (Capture, Get, JSON, NoContent, Optional, Post, QueryParam', Required, Summary, (:>))
-import Servant.API.Generic (GenericMode ((:-)))
+import Servant.API (Capture, Get, JSON, NoContent, Optional, Post, QueryParam', Required, Summary, (:-), (:>))
 
 data EffectsAPI auth f = EffectsAPI
   { getEffect ::
-      f :- Summary "Read effect events"
-        :> "jobs"
-        :> Capture "jobId" (Id Job)
-        :> "effects"
-        :> Capture "attribute" AttributePath
-        :> auth
-        :> Get '[JSON] EffectInfo,
+      f
+        :- Summary "Read effect events"
+          :> "jobs"
+          :> Capture "jobId" (Id Job)
+          :> "effects"
+          :> Capture "attribute" AttributePath
+          :> auth
+          :> Get '[JSON] EffectInfo,
     getEffectLog ::
-      f :- Summary "Read all recorded log entries"
-        :> "jobs"
-        :> Capture "jobId" (Id Job)
-        :> "effects"
-        :> Capture "attribute" AttributePath
-        :> "log"
-        :> "lines"
-        :> QueryParam' '[Required] "logId" (Id "log")
-        :> QueryParam' '[Optional] "iMin" Int
-        :> auth
-        :> Get '[JSON] Log,
+      f
+        :- Summary "Read all recorded log entries"
+          :> "jobs"
+          :> Capture "jobId" (Id Job)
+          :> "effects"
+          :> Capture "attribute" AttributePath
+          :> "log"
+          :> "lines"
+          :> QueryParam' '[Required] "logId" (Id "log")
+          :> QueryParam' '[Optional] "iMin" Int
+          :> auth
+          :> Get '[JSON] Log,
     cancelEffect ::
-      f :- Summary "Cancel the effect. It will cause the Job to have a failed status."
-        :> "jobs"
-        :> Capture "jobId" (Id Job)
-        :> "effects"
-        :> Capture "attribute" AttributePath
-        :> "cancel"
-        :> auth
-        :> Post '[JSON] NoContent
+      f
+        :- Summary "Cancel the effect. It will cause the Job to have a failed status."
+          :> "jobs"
+          :> Capture "jobId" (Id Job)
+          :> "effects"
+          :> Capture "attribute" AttributePath
+          :> "cancel"
+          :> auth
+          :> Post '[JSON] NoContent
   }
   deriving (Generic)
diff --git a/src/Hercules/API/Health.hs b/src/Hercules/API/Health.hs
--- a/src/Hercules/API/Health.hs
+++ b/src/Hercules/API/Health.hs
@@ -2,24 +2,27 @@
 
 module Hercules.API.Health where
 
+import Hercules.API.Prelude
 import Servant.API
-import Servant.API.Generic
 
 data HealthAPI auth f = HealthAPI
   { db ::
-      f :- Summary "Health check for the database"
-        :> "health"
-        :> "db"
-        :> Get '[JSON] NoContent,
+      f
+        :- Summary "Health check for the database"
+          :> "health"
+          :> "db"
+          :> Get '[JSON] NoContent,
     queue ::
-      f :- Summary "Health check for the queue"
-        :> "health"
-        :> "queue"
-        :> Get '[JSON] NoContent,
+      f
+        :- Summary "Health check for the queue"
+          :> "health"
+          :> "queue"
+          :> Get '[JSON] NoContent,
     github ::
-      f :- Summary "Health check for the github"
-        :> "health"
-        :> "github"
-        :> Get '[JSON] NoContent
+      f
+        :- Summary "Health check for the github"
+          :> "health"
+          :> "github"
+          :> Get '[JSON] NoContent
   }
   deriving (Generic)
diff --git a/src/Hercules/API/Organizations.hs b/src/Hercules/API/Organizations.hs
--- a/src/Hercules/API/Organizations.hs
+++ b/src/Hercules/API/Organizations.hs
@@ -13,46 +13,50 @@
 import Hercules.API.Organizations.PaymentLink (PaymentLink)
 import Hercules.API.Prelude
 import Servant.API
-import Servant.API.Generic
 
 data OrganizationsAPI auth f = OrganizationsAPI
   { findOrganizations ::
-      f :- Summary "Get all organizations user has admin access to"
-        :> auth
-        :> "api"
-        :> "organizations"
-        :> Get '[JSON] [Organization],
+      f
+        :- Summary "Get all organizations user has admin access to"
+          :> auth
+          :> "api"
+          :> "organizations"
+          :> Get '[JSON] [Organization],
     createOrganization ::
-      f :- Summary "Create a new organization"
-        :> auth
-        :> "api"
-        :> "organizations"
-        :> ReqBody '[JSON] CreateOrganization
-        :> Post '[JSON] Organization,
+      f
+        :- Summary "Create a new organization"
+          :> auth
+          :> "api"
+          :> "organizations"
+          :> ReqBody '[JSON] CreateOrganization
+          :> Post '[JSON] Organization,
     connectAccountToOrganization ::
-      f :- Summary "Connect an account to an organization"
-        :> auth
-        :> "api"
-        :> "organizations"
-        :> Capture "organizationId" (Id Organization)
-        :> "accounts"
-        :> Capture "accountId" (Id Account)
-        :> Post '[JSON] NoContent,
+      f
+        :- Summary "Connect an account to an organization"
+          :> auth
+          :> "api"
+          :> "organizations"
+          :> Capture "organizationId" (Id Organization)
+          :> "accounts"
+          :> Capture "accountId" (Id Account)
+          :> Post '[JSON] NoContent,
     paymentLinkForOrganization ::
-      f :- Summary "Generate payment link for an organization"
-        :> auth
-        :> "api"
-        :> "organizations"
-        :> Capture "organizationId" (Id Organization)
-        :> "paymentLink"
-        :> Post '[JSON] PaymentLink,
+      f
+        :- Summary "Generate payment link for an organization"
+          :> auth
+          :> "api"
+          :> "organizations"
+          :> Capture "organizationId" (Id Organization)
+          :> "paymentLink"
+          :> Post '[JSON] PaymentLink,
     getOrganizationActiveUsers ::
-      f :- Summary "List the active users in an organization's accounts."
-        :> auth
-        :> "api"
-        :> "organizations"
-        :> Capture "organizationId" (Id Organization)
-        :> "billing"
-        :> Get '[JSON] BillingInfo
+      f
+        :- Summary "List the active users in an organization's accounts."
+          :> auth
+          :> "api"
+          :> "organizations"
+          :> Capture "organizationId" (Id Organization)
+          :> "billing"
+          :> Get '[JSON] BillingInfo
   }
   deriving (Generic)
diff --git a/src/Hercules/API/Projects.hs b/src/Hercules/API/Projects.hs
--- a/src/Hercules/API/Projects.hs
+++ b/src/Hercules/API/Projects.hs
@@ -28,25 +28,26 @@
   ( SourceHostingSite,
   )
 import Servant.API
-import Servant.API.Generic
 
 data ProjectResourceGroup auth f = ProjectResourceGroup
   { getJobs ::
-      f :- Summary "Retrieve information about jobs"
-        :> "jobs"
-        :> QueryParam' '[Optional, Description "Constrain the results by git ref, such as refs/heads/my-branch or HEAD"] "ref" Text
-        :> QueryParam' '[Optional, Description "Only return successful jobs, or only failed ones"] "success" Bool
-        :> QueryParam' '[Optional, Description "Return jobs that come \"after\" the provided id in the response order."] "offsetId" (Id Job)
-        :> auth
-        :> Get '[JSON] PagedJobs,
+      f
+        :- Summary "Retrieve information about jobs"
+          :> "jobs"
+          :> QueryParam' '[Optional, Description "Constrain the results by git ref, such as refs/heads/my-branch or HEAD"] "ref" Text
+          :> QueryParam' '[Optional, Description "Only return successful jobs, or only failed ones"] "success" Bool
+          :> QueryParam' '[Optional, Description "Return jobs that come \"after\" the provided id in the response order."] "offsetId" (Id Job)
+          :> auth
+          :> Get '[JSON] PagedJobs,
     getJobSource ::
-      f :- Summary "Get source information from the latest successful job/jobs satisfying the provided requirements."
-        :> Description "The job parameter can be omitted to require all jobs for a commit to succeed. This can have the unexpected effect of reverting when a change in the extraInputs causes a regression. So it is recommended to specify one or more jobs. Common examples are \"onPush.default\" for a pinned build or \"onPush.ci\" for a build using extraInputs to integrate continuously."
-        :> "source"
-        :> QueryParam' '[Optional, Description "Constrain the results by git ref, such as refs/heads/my-branch. Defaults to HEAD."] "ref" Text
-        :> QueryParams "jobs" Text
-        :> auth
-        :> Get '[JSON] ImmutableGitInput
+      f
+        :- Summary "Get source information from the latest successful job/jobs satisfying the provided requirements."
+          :> Description "The job parameter can be omitted to require all jobs for a commit to succeed. This can have the unexpected effect of reverting when a change in the extraInputs causes a regression. So it is recommended to specify one or more jobs. Common examples are \"onPush.default\" for a pinned build or \"onPush.ci\" for a build using extraInputs to integrate continuously."
+          :> "source"
+          :> QueryParam' '[Optional, Description "Constrain the results by git ref, such as refs/heads/my-branch. Defaults to HEAD."] "ref" Text
+          :> QueryParams "jobs" Text
+          :> auth
+          :> Get '[JSON] ImmutableGitInput
   }
   deriving (Generic)
 
@@ -72,99 +73,110 @@
              )
              (ToServantApi (ProjectResourceGroup auth)),
     projectsByOwner ::
-      f :- Summary "List all projects owned by an account."
-        :> "accounts"
-        :> Capture' '[Required, Strict] "accountId" (Id Account)
-        :> "projects"
-        :> auth
-        :> Get '[JSON] [Project],
+      f
+        :- Summary "List all projects owned by an account."
+          :> "accounts"
+          :> Capture' '[Required, Strict] "accountId" (Id Account)
+          :> "projects"
+          :> auth
+          :> Get '[JSON] [Project],
     findProjects ::
-      f :- Summary "Find projects"
-        :> "projects"
-        :> QueryParam' '[Optional] "site" (Name SourceHostingSite)
-        :> QueryParam' '[Optional] "account" (Name Account)
-        :> QueryParam' '[Optional] "project" (Name Project)
-        :> auth
-        :> Get '[JSON] [Project],
+      f
+        :- Summary "Find projects"
+          :> "projects"
+          :> QueryParam' '[Optional] "site" (Name SourceHostingSite)
+          :> QueryParam' '[Optional] "account" (Name Account)
+          :> QueryParam' '[Optional] "project" (Name Project)
+          :> auth
+          :> Get '[JSON] [Project],
     createProject ::
-      f :- Summary "Create a new project."
-        :> "projects"
-        :> auth
-        :> ReqBody '[JSON] CreateProject
-        :> Post '[JSON] (Id Project),
+      f
+        :- Summary "Create a new project."
+          :> "projects"
+          :> auth
+          :> ReqBody '[JSON] CreateProject
+          :> Post '[JSON] (Id Project),
     patchProject ::
-      f :- Summary "Modify a project"
-        :> "projects"
-        :> Capture' '[Required, Strict] "projectId" (Id Project)
-        :> ReqBody '[JSON] PatchProject
-        :> auth
-        :> Patch '[JSON] Project,
+      f
+        :- Summary "Modify a project"
+          :> "projects"
+          :> Capture' '[Required, Strict] "projectId" (Id Project)
+          :> ReqBody '[JSON] PatchProject
+          :> auth
+          :> Patch '[JSON] Project,
     createUserEffectToken ::
-      f :- Summary "Create a token for local effect execution"
-        :> "projects"
-        :> Capture' '[Required, Strict] "projectId" (Id Project)
-        :> auth
-        :> "create-user-effect-token"
-        :> Post '[JSON] CreateUserEffectTokenResponse,
+      f
+        :- Summary "Create a token for local effect execution"
+          :> "projects"
+          :> Capture' '[Required, Strict] "projectId" (Id Project)
+          :> auth
+          :> "create-user-effect-token"
+          :> Post '[JSON] CreateUserEffectTokenResponse,
     findJobs ::
-      f :- Summary "Find jobs"
-        :> "jobs"
-        :> QueryParam' '[Optional, Description "Currently only \"github\" or omit entirely"] "site" (Name SourceHostingSite)
-        :> QueryParam' '[Optional, Description "Account name filter"] "account" (Name Account)
-        :> QueryParam' '[Optional, Description "Project name filter. Required if you want to retrieve all jobs"] "project" (Name Project)
-        :> QueryParam' '[Optional, Description "To get a specific job by index"] "index" Int
-        :> QueryParam' '[Optional, Description "Number of latest jobs to get, when project name is omitted. Range [1..50], default 10."] "latest" Int
-        :> auth
-        :> Get '[JSON] [ProjectAndJobs],
+      f
+        :- Summary "Find jobs"
+          :> "jobs"
+          :> QueryParam' '[Optional, Description "Currently only \"github\" or omit entirely"] "site" (Name SourceHostingSite)
+          :> QueryParam' '[Optional, Description "Account name filter"] "account" (Name Account)
+          :> QueryParam' '[Optional, Description "Project name filter. Required if you want to retrieve all jobs"] "project" (Name Project)
+          :> QueryParam' '[Optional, Description "To get a specific job by index"] "index" Int
+          :> QueryParam' '[Optional, Description "Number of latest jobs to get, when project name is omitted. Range [1..50], default 10."] "latest" Int
+          :> auth
+          :> Get '[JSON] [ProjectAndJobs],
     projectJobEvaluation ::
-      f :- Summary "List all attributes in a job"
-        :> Description "A list of all attributes that have been produced as part of the evaluation of a job."
-        :> "jobs"
-        :> Capture' '[Required, Strict] "jobId" (Id Job)
-        :> "evaluation"
-        :> auth
-        :> Get '[JSON] EvaluationDetail,
+      f
+        :- Summary "List all attributes in a job"
+          :> Description "A list of all attributes that have been produced as part of the evaluation of a job."
+          :> "jobs"
+          :> Capture' '[Required, Strict] "jobId" (Id Job)
+          :> "evaluation"
+          :> auth
+          :> Get '[JSON] EvaluationDetail,
     jobDerivationFailureGraph ::
-      f :- Summary "Find all failures in an evaluation's derivations"
-        :> Description
-             "Returns all derivations that have failures in their dependency closures."
-        :> "jobs"
-        :> Capture' '[Required, Strict] "jobId" (Id Job)
-        :> "derivations"
-        :> "failed"
-        :> auth
-        :> Get '[JSON] FailureGraph.Graph,
+      f
+        :- Summary "Find all failures in an evaluation's derivations"
+          :> Description
+               "Returns all derivations that have failures in their dependency closures."
+          :> "jobs"
+          :> Capture' '[Required, Strict] "jobId" (Id Job)
+          :> "derivations"
+          :> "failed"
+          :> auth
+          :> Get '[JSON] FailureGraph.Graph,
     jobRerun ::
-      f :- Summary "Create a new job like this job"
-        :> Description
-             "The newly created job will be in the same project, have the same inputs but a new evaluation.\
-             \ The response has the newly created job."
-        :> "jobs"
-        :> Capture' '[Required, Strict] "jobId" (Id Job)
-        :> "rerun"
-        :> QueryParam "rebuildFailures" Bool
-        :> auth
-        :> Post '[JSON] Job,
+      f
+        :- Summary "Create a new job like this job"
+          :> Description
+               "The newly created job will be in the same project, have the same inputs but a new evaluation.\
+               \ The response has the newly created job."
+          :> "jobs"
+          :> Capture' '[Required, Strict] "jobId" (Id Job)
+          :> "rerun"
+          :> QueryParam "rebuildFailures" Bool
+          :> auth
+          :> Post '[JSON] Job,
     jobCancel ::
-      f :- Summary "Cancel the job and any work that becomes redundant"
-        :> Description
-             "Some derivations may keep going, if referenced by active jobs."
-        :> "jobs"
-        :> Capture' '[Required, Strict] "jobId" (Id Job)
-        :> "cancel"
-        :> auth
-        :> Post '[JSON] NoContent,
+      f
+        :- Summary "Cancel the job and any work that becomes redundant"
+          :> Description
+               "Some derivations may keep going, if referenced by active jobs."
+          :> "jobs"
+          :> Capture' '[Required, Strict] "jobId" (Id Job)
+          :> "cancel"
+          :> auth
+          :> Post '[JSON] NoContent,
     getEvaluationLog ::
-      f :- Summary "Read all recorded evaluation log entries"
-        :> "jobs"
-        :> Capture' '[Required, Strict] "jobId" (Id Job)
-        :> "evaluation"
-        :> "log"
-        :> "lines"
-        :> QueryParam' '[Required] "logId" (Id "log")
-        :> QueryParam' '[Optional] "iMin" Int
-        :> auth
-        :> Get '[JSON] Log
+      f
+        :- Summary "Read all recorded evaluation log entries"
+          :> "jobs"
+          :> Capture' '[Required, Strict] "jobId" (Id Job)
+          :> "evaluation"
+          :> "log"
+          :> "lines"
+          :> QueryParam' '[Required] "logId" (Id "log")
+          :> QueryParam' '[Optional] "iMin" Int
+          :> auth
+          :> Get '[JSON] Log
   }
   deriving (Generic)
 
diff --git a/src/Hercules/API/Repos.hs b/src/Hercules/API/Repos.hs
--- a/src/Hercules/API/Repos.hs
+++ b/src/Hercules/API/Repos.hs
@@ -7,21 +7,22 @@
 import Hercules.API.Repos.Repo (Repo)
 import Hercules.API.Repos.RepoKey (RepoKey)
 import Servant.API
-import Servant.API.Generic
 
 data ReposAPI auth f = ReposAPI
   { reposByOwner ::
-      f :- Summary "Repositories that the account owns or has explicit access to."
-        :> "accounts"
-        :> Capture' '[Required, Strict] "accountId" (Id Account)
-        :> "repos"
-        :> auth
-        :> Get '[JSON] [Repo],
+      f
+        :- Summary "Repositories that the account owns or has explicit access to."
+          :> "accounts"
+          :> Capture' '[Required, Strict] "accountId" (Id Account)
+          :> "repos"
+          :> auth
+          :> Get '[JSON] [Repo],
     parseGitURL ::
-      f :- Summary "Parse a git remote URL into site, owner and repo. Returns 400 if invalid, 404 if the site can not be determined. Does provide any guarantee that the repository exists."
-        :> "parse-git-url"
-        :> QueryParam' '[Required, Strict] "gitURL" Text
-        :> auth
-        :> Get '[JSON] RepoKey
+      f
+        :- Summary "Parse a git remote URL into site, owner and repo. Returns 400 if invalid, 404 if the site can not be determined. Does provide any guarantee that the repository exists."
+          :> "parse-git-url"
+          :> QueryParam' '[Required, Strict] "gitURL" Text
+          :> auth
+          :> Get '[JSON] RepoKey
   }
   deriving (Generic)
diff --git a/src/Hercules/API/State.hs b/src/Hercules/API/State.hs
--- a/src/Hercules/API/State.hs
+++ b/src/Hercules/API/State.hs
@@ -16,7 +16,6 @@
 import Hercules.API.State.StateLockAcquireResponse (StateLockAcquireResponse, StateLockAcquiredResponse)
 import Hercules.API.State.StateLockUpdateRequest (StateLockUpdateRequest)
 import Servant.API
-import Servant.API.Generic
 
 -- | A newtype wrapper for servant-swagger
 newtype RawBytes = RawBytes {fromRawBytes :: ByteString}
@@ -31,33 +30,37 @@
 
 data ProjectStateResourceGroup auth f = ProjectStateResourceGroup
   { putStateData ::
-      f :- Summary "Upload a state file"
-        :> "state"
-        :> Capture' '[Required, Strict] "stateName" Text
-        :> "data"
-        :> StreamBody NoFraming OctetStream (SourceIO RawBytes)
-        :> auth
-        :> Put '[JSON] NoContent,
+      f
+        :- Summary "Upload a state file"
+          :> "state"
+          :> Capture' '[Required, Strict] "stateName" Text
+          :> "data"
+          :> StreamBody NoFraming OctetStream (SourceIO RawBytes)
+          :> auth
+          :> Put '[JSON] NoContent,
     getStates ::
-      f :- Summary "List all state files"
-        :> "states"
-        :> auth
-        :> Get '[JSON] ProjectState,
+      f
+        :- Summary "List all state files"
+          :> "states"
+          :> auth
+          :> Get '[JSON] ProjectState,
     getStateData ::
-      f :- Summary "Download a state file"
-        :> "state"
-        :> Capture' '[Required, Strict] "stateName" Text
-        :> "data"
-        :> QueryParam' '[Optional, Strict] "version" Int
-        :> auth
-        :> StreamGet NoFraming OctetStream (Headers '[ContentLength, ContentDisposition] (SourceIO RawBytes)),
+      f
+        :- Summary "Download a state file"
+          :> "state"
+          :> Capture' '[Required, Strict] "stateName" Text
+          :> "data"
+          :> QueryParam' '[Optional, Strict] "version" Int
+          :> auth
+          :> StreamGet NoFraming OctetStream (Headers '[ContentLength, ContentDisposition] (SourceIO RawBytes)),
     acquireLock ::
-      f :- Summary "Acquire a lock"
-        :> "lock"
-        :> Capture' '[Required, Strict] "lockName" Text
-        :> ReqBody '[JSON] StateLockAcquireRequest
-        :> auth
-        :> Post '[JSON] StateLockAcquireResponse
+      f
+        :- Summary "Acquire a lock"
+          :> "lock"
+          :> Capture' '[Required, Strict] "lockName" Text
+          :> ReqBody '[JSON] StateLockAcquireRequest
+          :> auth
+          :> Post '[JSON] StateLockAcquireResponse
   }
   deriving (Generic)
 
@@ -83,15 +86,17 @@
              )
              (ToServantApi (ProjectStateResourceGroup auth)),
     updateLockLease ::
-      f :- "lock-leases"
-        :> Capture' '[Required, Strict] "lockLeaseId" (Id "StateLockLease")
-        :> ReqBody '[JSON] StateLockUpdateRequest
-        :> auth
-        :> Post '[JSON] StateLockAcquiredResponse,
+      f
+        :- "lock-leases"
+          :> Capture' '[Required, Strict] "lockLeaseId" (Id "StateLockLease")
+          :> ReqBody '[JSON] StateLockUpdateRequest
+          :> auth
+          :> Post '[JSON] StateLockAcquiredResponse,
     deleteLockLease ::
-      f :- "lock-leases"
-        :> Capture' '[Required, Strict] "lockLeaseId" (Id "StateLockLease")
-        :> auth
-        :> Delete '[JSON] NoContent
+      f
+        :- "lock-leases"
+          :> Capture' '[Required, Strict] "lockLeaseId" (Id "StateLockLease")
+          :> auth
+          :> Delete '[JSON] NoContent
   }
   deriving (Generic)
diff --git a/src/Hercules/Frontend.hs b/src/Hercules/Frontend.hs
--- a/src/Hercules/Frontend.hs
+++ b/src/Hercules/Frontend.hs
@@ -11,7 +11,6 @@
   )
 import Network.URI
 import Servant.API
-import Servant.API.Generic
 import Servant.Links
 
 -- | URL routes for the web interface.
@@ -22,25 +21,31 @@
       f
         :- view,
     account ::
-      f :- Capture' [Required, Strict] "site" (Name SourceHostingSite)
-        :> Capture' [Required, Strict] "account" (Name Account)
-        :> view,
+      f
+        :- Capture' [Required, Strict] "site" (Name SourceHostingSite)
+          :> Capture' [Required, Strict] "account" (Name Account)
+          :> view,
     cliAuthorize ::
-      f :- "settings" :> "cli" :> "authorize"
-        :> QueryParam' [Required, Strict] "token" Text
-        :> view,
+      f
+        :- "settings"
+          :> "cli"
+          :> "authorize"
+          :> QueryParam' [Required, Strict] "token" Text
+          :> view,
     project ::
-      f :- Capture' [Required, Strict] "site" (Name SourceHostingSite)
-        :> Capture' [Required, Strict] "account" (Name Account)
-        :> Capture' [Required, Strict] "project" (Name Project)
-        :> view,
+      f
+        :- Capture' [Required, Strict] "site" (Name SourceHostingSite)
+          :> Capture' [Required, Strict] "account" (Name Account)
+          :> Capture' [Required, Strict] "project" (Name Project)
+          :> view,
     job ::
-      f :- Capture' [Required, Strict] "site" (Name SourceHostingSite)
-        :> Capture' [Required, Strict] "account" (Name Account)
-        :> Capture' [Required, Strict] "project" (Name Project)
-        :> "jobs"
-        :> Capture' [Required, Strict] "jobIndex" Int
-        :> view,
+      f
+        :- Capture' [Required, Strict] "site" (Name SourceHostingSite)
+          :> Capture' [Required, Strict] "account" (Name Account)
+          :> Capture' [Required, Strict] "project" (Name Project)
+          :> "jobs"
+          :> Capture' [Required, Strict] "jobIndex" Int
+          :> view,
     notificationSettings ::
       f
         :- "settings" :> "notifications" :> view
