diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Change log
+
+## 0.1.0
+
+* Initial release: tokenCost, requestCost, cacheSavings, monthlyBill.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+# ai-serving-cost
+
+Restate an AI API bill from tokens, rates, and cache share, the way a
+cost audit would: input and output priced separately, the cache
+discount taken off the input side, the per-request floor added back.
+
+Rates are per million tokens. A workload of 10,000 input and 500
+output tokens at $3 and $15 per million, with a $0.0005 per-request
+fee, costs $0.038 uncached and $0.029 at a 30 percent cache hit rate.
+At 20,000 requests a day that is $17,400 for the month, and the cache
+is saving $60 of every $150 the input side would otherwise pay on
+50 million tokens.
+
+The package follows the serving-math method used on
+[Pastagi](https://pastagi.com). It depends only on base.
+
+## Example
+
+```
+requestCost 10000 500 3.0 15.0 0.3 0.0005  -- 0.029
+cacheSavings 50000000 3.0 0.4              -- 60.0
+monthlyBill 0.029 20000                    -- 17400.0
+```
diff --git a/ai-serving-cost.cabal b/ai-serving-cost.cabal
new file mode 100644
--- /dev/null
+++ b/ai-serving-cost.cabal
@@ -0,0 +1,35 @@
+cabal-version:      2.2
+name:               ai-serving-cost
+version:            0.1.0
+synopsis:           Restate an AI API bill from tokens, rates, and cache share
+description:
+  An API bill is a token count times a rate, minus whatever the cache
+  knocks off, plus a per-request floor. These functions compute that
+  math directly: price a single request from its input and output
+  tokens, price the cache discount at a given volume, and scale a
+  per-request cost to a 30-day monthly bill. An audit can restate the
+  invoice line by line instead of trusting the provider's summary.
+  .
+  Companion to Pastagi, which publishes AI cost audits and serving
+  math. Five pure functions, no dependencies beyond base.
+license:            MIT
+author:             Poket Dev
+maintainer:         hello@poketdev.com
+homepage:           https://pastagi.com
+bug-reports:        https://github.com/scrapertweeter3-prog/ai-serving-cost-hs/issues
+copyright:          2026 Poket Dev LLC
+category:           Math
+build-type:         Simple
+extra-doc-files:    README.md
+                  , CHANGELOG.md
+
+source-repository head
+  type:     git
+  location: https://github.com/scrapertweeter3-prog/ai-serving-cost-hs
+
+library
+  exposed-modules:  AiServing.Cost
+  hs-source-dirs:   src
+  build-depends:    base >=4 && <5
+  default-language: Haskell2010
+  ghc-options:      -Wall
diff --git a/src/AiServing/Cost.hs b/src/AiServing/Cost.hs
new file mode 100644
--- /dev/null
+++ b/src/AiServing/Cost.hs
@@ -0,0 +1,34 @@
+module AiServing.Cost
+  ( tokenCost
+  , requestCost
+  , cacheSavings
+  , monthlyBill
+  ) where
+
+-- | Dollar cost of a token count at a per-million-token rate.
+tokenCost :: Double -> Double -> Double
+tokenCost tokens ratePerMillion = tokens / 1000000.0 * ratePerMillion
+
+-- | Cost of one request when input tokens, output tokens, and a
+-- per-request fee all land on the same bill. A cached share of the
+-- input traffic bills at the discounted rate, so the input cost
+-- shrinks by that share. The cache share clamps to [0, 1].
+requestCost :: Double -> Double -> Double -> Double -> Double -> Double -> Double
+requestCost inputTokens outputTokens inputRate outputRate cacheShare perRequest =
+  inCost + outCost + perRequest
+  where
+    share   = max 0.0 (min 1.0 cacheShare)
+    inCost  = tokenCost inputTokens inputRate * (1.0 - share)
+    outCost = tokenCost outputTokens outputRate
+
+-- | Dollars a cached share of input traffic saves at a given volume,
+-- floored at zero when the share is nonsense.
+cacheSavings :: Double -> Double -> Double -> Double
+cacheSavings tokens inputRate cacheShare =
+  tokenCost tokens inputRate * max 0.0 (min 1.0 cacheShare)
+
+-- | Monthly bill for a workload: per-request cost times requests per
+-- day, over a 30-day month.
+monthlyBill :: Double -> Double -> Double
+monthlyBill costPerRequest requestsPerDay =
+  costPerRequest * requestsPerDay * 30.0
