diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,1 @@
+2019 Feb 3 - Initial release, v1.0.0.0
diff --git a/leanpub-concepts.cabal b/leanpub-concepts.cabal
new file mode 100644
--- /dev/null
+++ b/leanpub-concepts.cabal
@@ -0,0 +1,39 @@
+cabal-version: 2.0
+
+name: leanpub-concepts
+version: 1.0.0.0
+
+synopsis: Types for the Leanpub API
+category: Web
+
+description:
+    This is a minimal package that just defines a common set of types
+    for working with the <https://leanpub.com/help/api Leanpub API>.
+
+homepage:    https://github.com/typeclasses/leanpub
+bug-reports: https://github.com/typeclasses/leanpub/issues
+
+author:     Chris Martin
+maintainer: Chris Martin, Julie Moronuki
+
+copyright: 2018 Typeclass Consulting, LLC
+license: MIT
+license-file: license.txt
+
+build-type: Simple
+tested-with: GHC==8.6.1
+
+extra-source-files:
+    changelog.md
+
+library
+    hs-source-dirs: library
+    default-language: Haskell2010
+
+    exposed-modules:
+        Leanpub.Concepts
+
+    build-depends:
+        base >=4.10 && <5
+      , bytestring
+      , text
diff --git a/library/Leanpub/Concepts.hs b/library/Leanpub/Concepts.hs
new file mode 100644
--- /dev/null
+++ b/library/Leanpub/Concepts.hs
@@ -0,0 +1,92 @@
+{-# OPTIONS_GHC -Wall #-}
+
+module Leanpub.Concepts
+  (
+  -- * API
+    ApiSecretKey (..)
+
+  -- * Books
+  , BookSlug (..)
+  , bookURL
+
+  -- * Coupons
+  , CouponCode (..)
+  , couponURL
+  , CouponMaxUses (..)
+  , CouponNote (..)
+
+  ) where
+
+-- base
+import Numeric.Natural (Natural)
+
+-- text
+import Data.Text (Text)
+import qualified Data.Text.Lazy         as LT
+import qualified Data.Text.Lazy.Builder as TB
+
+{- | Get an API key from the
+<https://leanpub.com/author_dashboard/settings Leanpub dashboard>.
+This API key should be kept private; treat it just like your password
+to your Leanpub account. -}
+
+newtype ApiSecretKey = ApiSecretKey Text
+
+{- | An identifier for a book. E.g. if your book is found at
+
+> https://leanpub.com/your_book
+
+then your book's slug is @your_book@. -}
+
+newtype BookSlug = BookSlug Text
+    deriving Show
+
+{- |
+>>> :set -XOverloadedStrings
+>>> bookURL (BookSlug "your_book")
+"https://leanpub.com/your_book"
+-}
+
+bookURL :: BookSlug -> Text
+bookURL (BookSlug book) =
+    (LT.toStrict . TB.toLazyText)
+        (  TB.fromString  "https://leanpub.com/"
+        <> TB.fromText    book
+        )
+
+{- | An identifier for a coupon. -}
+
+newtype CouponCode = CouponCode Text
+    deriving Show
+
+{- | E.g. if your book's slug is @your_book@ and the coupon code is
+@black_friday@ then users can use your coupon via the URL:
+
+> https://leanpub.com/your_book/c/black_friday
+
+>>> :set -XOverloadedStrings
+>>> couponURL (BookSlug "your_book") (CouponCode "black_friday")
+"https://leanpub.com/your_book/c/black_friday"
+-}
+
+couponURL :: BookSlug -> CouponCode -> Text
+couponURL (BookSlug book) (CouponCode coupon) =
+    (LT.toStrict . TB.toLazyText)
+        (  TB.fromString  "https://leanpub.com/"
+        <> TB.fromText    book
+        <> TB.fromString  "/c/"
+        <> TB.fromText    coupon
+        )
+
+data CouponMaxUses
+    = CouponUseUnlimited
+        -- ^ There is no limit to how many times the coupon may be used.
+    | CouponMaxUses Natural
+        -- ^ The maximum number of times the coupon may be used.
+    deriving Show
+
+{- | A description of a coupon. This is just used to remind you of what it was
+for; it is not visible to users. -}
+
+data CouponNote = CouponNote Text
+    deriving Show
diff --git a/license.txt b/license.txt
new file mode 100644
--- /dev/null
+++ b/license.txt
@@ -0,0 +1,18 @@
+Copyright 2019 Typeclass Consulting, LLC
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
