diff --git a/packages/docs/public/llms-full.txt b/packages/docs/public/llms-full.txt
index e7861a381..775ae5698 100644
--- a/packages/docs/public/llms-full.txt
+++ b/packages/docs/public/llms-full.txt
@@ -3,7 +3,7 @@
> OpenIAP: Unified in-app purchase specification for iOS & Android
> Documentation: https://openiap.dev
> Quick Reference: https://openiap.dev/llms.txt
-> Generated: 2026-08-01T17:31:39.495Z
+> Generated: 2026-08-01T22:00:58.764Z
## Table of Contents
1. Installation
@@ -2024,6 +2024,12 @@ private state machine and retention policy.
IAPKit lives in the OpenIAP monorepo as a Bun + Hono server, Convex backend,
and React SPA deployed behind one origin.
+The official hosted service is free under fair-use safeguards on shared,
+community-funded capacity. It is best-effort, not unlimited or SLA-backed.
+High-volume apps should contact hyo@hyo.dev before launch, help fund shared
+capacity through GitHub Sponsors or OpenCollective, or self-host the
+MIT-licensed server for dedicated capacity.
+
## API quick reference
Base URL: https://kit.openiap.dev
@@ -2056,7 +2062,7 @@ IAPKit does not relay those events through SSE, WebSockets, push, or long
polling. Apps persist only the user-scoped fields they need and conditionally
refresh on cold start, stale foreground, or explicit user action. Each refresh
still performs one mutation-free indexed Convex query so an expiry with no new
-webhook is detected. Respect `429 Retry-After`, coalesce concurrent refreshes,
+webhook is detected. Respect the `Retry-After` header on `429` and `503`, coalesce concurrent refreshes,
and enforce an app-defined maximum stale age for offline fallback. Secret-key
responses are `private, no-store` and omit `ETag`. The current
`kitApi.status()` and `kitApi.entitlements()` helpers are unconditional,
@@ -2130,15 +2136,29 @@ Harmonized `state` values (truthy `isValid`): `ENTITLED`,
- `403 INSUFFICIENT_SCOPE` — publishable key used for an administrative operation
- `403 INVALID_API_KEY` — wrong scheme or malformed key (format check only)
- `410 SECRET_API_KEY_IN_URL` — move the secret to `Authorization: Bearer ...` on the canonical route
-- `429 RATE_LIMITED` — per-key bucket empty; honor `Retry-After` seconds
+- `429 RATE_LIMITED` — API-key, source-IP, or process bucket empty; inspect `X-RateLimit-Scope` and honor `Retry-After`
+- `503 SERVICE_BUSY` — the API-key, source-IP, or process verification share is full; inspect `X-Concurrency-Scope` and retry with jittered backoff
- `500 UNKNOWN_ERROR` — quote the `X-Correlation-Id` header in a support ticket
-## Response headers (on 2xx / 4xx validation / 429)
+## Response headers
- `X-Correlation-Id` — UUIDv4, matches the stdout log line
- `X-RateLimit-Limit` — bucket capacity (default 600 per key)
- `X-RateLimit-Remaining` — tokens left in the bucket
-- `Retry-After` (429 only) — seconds to wait
+- `X-RateLimit-Scope` — rejecting `key`, source `ip`, or process `global` bucket on `RATE_LIMITED`
+- `X-Concurrency-Limit` / `X-Concurrency-Remaining` — verification slots for the reported axis after the request reaches the in-flight guard
+- `X-Concurrency-Scope` — `key`, trusted source `ip`, or process `global`
+- `Retry-After` (429 / 503) — seconds to wait
+
+Default protection is 600 burst / 10 req/sec per key, 600 / 5 req/sec
+per source IP, 5,000 / 100 req/sec per process, 8 concurrent verify handlers per
+API key, 16 per trusted source IP, and 32 per process. The key and source shares
+make simple credential rotation insufficient to monopolize the process from one
+network source. Fly Proxy separately
+limits the complete service to 80 soft / 120 hard concurrent requests per
+machine. One million requests per day average about 11.6 req/sec before peaks,
+so apps at that scale must coordinate capacity or self-host rather than
+assuming DAU implies safe request volume.
## Docs
@@ -2149,7 +2169,7 @@ Harmonized `state` values (truthy `isValid`): `ENTITLED`,
- [/docs/verification/google](https://kit.openiap.dev/docs/verification/google) — package name, service account JSON
- [/docs/verification/horizon](https://kit.openiap.dev/docs/verification/horizon) — App ID + App Secret (write-only)
- [/docs/api](https://kit.openiap.dev/docs/api) — request shapes, responses, errors, headers, and Amazon RVS payloads
-- [/docs/operations](https://kit.openiap.dev/docs/operations) — rate limits, logs, `/health`, graceful shutdown
+- [/docs/operations](https://kit.openiap.dev/docs/operations) — fair use, capacity, rate and concurrency limits, logs, `/health`, graceful shutdown
- [openiap.dev/docs/webhooks](https://openiap.dev/docs/webhooks) — operator setup steps for inbound Apple ASN v2 and Google RTDN lifecycle delivery
- [/docs/ai-assistants](https://kit.openiap.dev/docs/ai-assistants) — how to point Codex / Claude / Cursor / etc. at this file
- [/docs/ai-assistants/codex-plugin](https://kit.openiap.dev/docs/ai-assistants/codex-plugin) — Codex plugin setup and self-hosted IAPKit MCP server option
diff --git a/packages/docs/public/llms.txt b/packages/docs/public/llms.txt
index ef6c44fc7..bec408dda 100644
--- a/packages/docs/public/llms.txt
+++ b/packages/docs/public/llms.txt
@@ -3,7 +3,7 @@
> OpenIAP: Unified in-app purchase specification for iOS & Android
> Documentation: https://openiap.dev
> Full Reference: https://openiap.dev/llms-full.txt
-> Generated: 2026-08-01T17:31:39.495Z
+> Generated: 2026-08-01T22:00:58.764Z
## Installation
diff --git a/packages/docs/src/pages/docs/kit-backend.tsx b/packages/docs/src/pages/docs/kit-backend.tsx
index dddf3c571..70a8969ae 100644
--- a/packages/docs/src/pages/docs/kit-backend.tsx
+++ b/packages/docs/src/pages/docs/kit-backend.tsx
@@ -741,6 +741,87 @@ async function refreshEntitlements(
+
+ The official hosted IAPKit service is open-source infrastructure
+ shared by the OpenIAP community. It is free under fair-use safeguards
+ and operated on a best-effort basis; it is not unlimited capacity and
+ does not include dedicated resources or an SLA.
+
+ Plan from request frequency and peak concurrency, not DAU alone. One
+ million users making one hosted request per day already averages about{' '}
+ 11.6 requests per second, before cold-start,
+ release-day, or notification-driven peaks. That average exceeds the
+ hosted default per-key steady rate of 10 requests per second.
+
+ Hosted purchase verification also limits work already in progress to{' '}
+
+ 8 handlers per API key, 16 per trusted source IP, and 32 per process
+
+ . The key and source shares make simple credential rotation
+ insufficient to monopolize the process from one network source;
+ requests beyond any axis receive
+ Contact us before a high-volume production launch.{' '}
+ If your organization expects to consume a meaningful share of hosted
+ capacity, we ask it to help fund server expansion, monitoring,
+ security, and load testing through{' '}
+
+ GitHub Sponsors
+ {' '}
+ or{' '}
+
+ OpenCollective
+
+ . Sponsorship supports shared capacity; it does not automatically
+ reserve dedicated resources or create an SLA.
+
+ For predictable capacity and full operational control,{' '}
+
+ self-host the MIT-licensed server
+
+ . For capacity planning or a separate written arrangement, contact{' '}
+ hyo@hyo.dev.
+
+ The official
+ If your organization expects sustained high volume or would use a
+ meaningful share of that capacity, we ask you to contact us before
+ launch and help fund the servers, monitoring, security, and load
+ testing your traffic requires. You can contribute through{' '}
+
+ GitHub Sponsors
+ {' '}
+ or{' '}
+
+ OpenCollective
+
+ .
+
+ Sponsorship strengthens shared capacity for everyone; it does not
+ automatically buy unlimited usage, dedicated resources, or an SLA.
+ Teams that need predictable scaling or full operational control
+ can{' '}
+
+ self-host the MIT-licensed server
+ {' '}
+ or contact{' '}
+
+ hyo@hyo.dev
+ {' '}
+ about a separate written arrangement.
+ 503 SERVICE_BUSY instead
+ of entering an unbounded server queue.
+
+
+ Retry-After header on 429 and{' '}
+ 503 with jittered backoff. A 304 saves
+ response transfer but still uses a Convex query invocation.
+
+ Keep Hosted IAPKit Shared and Sustainable
+
+ kit.openiap.dev service runs the
+ open-source IAPKit backend as shared infrastructure for the whole
+ ecosystem. It is free under fair-use safeguards, best-effort, and
+ intentionally available to developers who cannot operate a
+ receipt-validation server themselves.
+
Why AI Can't Replace This Work
@@ -251,7 +332,8 @@ function Sponsors() {
>
GitHub Sponsors is the primary funding channel. Tiers scale from
individual contributors to companies shipping OpenIAP in
- production — details are on the GitHub page.
+ production. OpenCollective is also available for transparent
+ community funding.
{ - "Thank you for supporting IAPKit. Your subscription has been cancelled and any unused portion refunded in full — there's nothing you need to do. The validation APIs and analytics you were using keep working." + "Thank you for supporting IAPKit. Your subscription has been cancelled and any unused portion refunded in full — there's nothing you need to do. The validation APIs and analytics you were using keep working under the shared hosted service's fair-use safeguards." }
{ - "Track validation usage and stored receipt analytics. Validation and analytics are free." + "Track validation usage and stored receipt analytics. Hosted IAPKit is free under fair-use limits on shared community infrastructure." }
{ - "Validation and analytics stay free for every developer. If your team or company depends on them, consider supporting the project so we can keep the core service running for thousands of indie developers." + "Hosted IAPKit is a shared, best-effort service rather than unlimited or SLA-backed infrastructure. If your organization expects to consume a meaningful share of capacity, contact us before launch and help fund the servers, monitoring, and security the ecosystem depends on." }
{ - "AI-assisted workflows may later use separate usage-based pricing because model token costs are real infrastructure costs." + "Sponsorship supports shared capacity; it does not automatically reserve dedicated resources or an SLA. Self-host the MIT-licensed server when you need predictable capacity and full operational control." }
- - {"Become a sponsor"} - + ++ {"Capacity planning: "} + + hyo@hyo.dev + +
304, replace it on{" "}
- 200, and respect 429 Retry-After.
+ 200, and respect the Retry-After header on{" "}
+ 429 or 503.
Every authenticated response (2xx, validation 4xx, 429) carries:
++ Verification requests that pass bearer-token shape validation carry a + correlation ID. Requests that reach the multi-axis rate limiter also + carry its limit and remaining-token headers: +
X-Correlation-Id — UUID for this request. Quote it in
@@ -510,7 +515,13 @@ async function refreshEntitlements(
- On 429 the response also carries Retry-After in seconds.
+ Verification responses that reach the in-flight guard also carry{" "}
+ X-Concurrency-Limit and{" "}
+ X-Concurrency-Remaining. X-Concurrency-Scope{" "}
+ identifies the reported API-key, trusted source-IP, or process-global
+ axis. A RATE_LIMITED response names its key, IP, or process
+ bucket in X-RateLimit-Scope. A 429 or application-generated
+ 503 response carries Retry-After in seconds.
401 / 403 responses from the auth layer run before the rate-limit @@ -587,10 +598,21 @@ async function refreshEntitlements( REPEATED_FAILURE
- /v1/purchase/verify is protected by an in-memory
- token-bucket keyed on a SHA-256 hash of the API key. Defaults:
- 600-request burst, 10 req/sec steady state —
- equivalently 600 req/min sustained. Self-hosted deployments can tune via{" "}
- RATE_LIMIT_CAPACITY and{" "}
- RATE_LIMIT_REFILL_PER_SEC.
+ Publishable-key routes are protected by bounded, in-memory token
+ buckets. Defaults are 600 burst / 10 req/sec per API
+ key, 600 burst / 5 req/sec per source IP, and{" "}
+ 5,000 burst / 100 req/sec for the whole process.
+ Self-hosted deployments can tune the RATE_LIMIT_*{" "}
+ environment variables.
When the bucket empties, IAPKit returns 429 RATE_LIMITED{" "}
@@ -42,6 +42,80 @@ export default function OperationsPage() {
+ Arrival rate and work already in progress are different limits. A slow
+ Apple, Google, Amazon, Meta, or Convex response can make accepted
+ verifications overlap, so each API key may occupy at most{" "}
+ 8 verification handlers, each trusted source IP at most{" "}
+ 16, and each process at most 32 by
+ default. The key and source shares make simple credential rotation
+ insufficient to monopolize the process from one network source. Excess
+ work is not queued in memory; it returns 503 SERVICE_BUSY{" "}
+ with Retry-After, X-Concurrency-Limit,{" "}
+ X-Concurrency-Remaining, and{" "}
+ X-Concurrency-Scope.
+
+ Self-hosters can tune VERIFY_MAX_IN_FLIGHT,{" "}
+ VERIFY_MAX_IN_FLIGHT_PER_KEY, and{" "}
+ VERIFY_MAX_IN_FLIGHT_PER_IP. Fly Proxy also uses request
+ concurrency limits for the whole HTTP service (80 soft, 120 hard per
+ machine) so static, read, and verification traffic cannot create an
+ unbounded number of requests inside one 512 MB machine.
+
+ Hosted IAPKit is open-source infrastructure shared by the OpenIAP + community. It is free without a request billing meter, best-effort, and + protected by fair-use safeguards; it is not unlimited capacity and does + not include dedicated resources or an SLA. +
+
+ One million users making one request per day average about 11.6
+ requests per second, already above the hosted default per-key steady
+ rate before launch-time or notification-driven peaks. Cache stable
+ data, coalesce refreshes, verify only after purchase or restore, and
+ honor the Retry-After header on 429 and{" "}
+ 503 with jittered backoff.
+
+ If your organization expects sustained high volume or a meaningful share + of hosted capacity, contact{" "} + + hyo@hyo.dev + {" "} + before launch. We ask organizations at that scale to help fund shared + capacity, monitoring, security, and load testing through{" "} + + GitHub Sponsors + {" "} + or{" "} + + OpenCollective + + . Sponsorship strengthens the shared service; it does not automatically + reserve capacity or create an SLA. For predictable scaling, self-host + the MIT-licensed server. +
+Every verify response after the auth-header shape check carries an{" "} diff --git a/packages/kit/src/pages/landing.tsx b/packages/kit/src/pages/landing.tsx index 3da488c1e..f5a51eecf 100644 --- a/packages/kit/src/pages/landing.tsx +++ b/packages/kit/src/pages/landing.tsx @@ -81,7 +81,9 @@ export default function LandingPage() {
- {"Validation and analytics are free for every developer."} + { + "Hosted validation and analytics are free under fair-use limits." + }
- {"No credit card for validation or analytics."} + { + "No credit card. Shared, community-funded infrastructure with best-effort availability." + }
@@ -242,44 +246,92 @@ export default function LandingPage() { - {/* Sponsorship Section */} + {/* Shared capacity and sponsorship section */}+
{ - "Core IAPKit validation and analytics are free for every developer. If your team depends on them, help sustain the project — every contribution keeps the foundation available for thousands of indie developers." + "Hosted IAPKit is an open-source community service that every developer can share. It has fair-use rate limits, does not include an SLA, and is not unlimited infrastructure." }
-- { - "Advanced AI-assisted workflows may be handled separately later, because model token costs are real infrastructure costs." - } -
-+ { + "Use the hosted service without a billing meter, cache reads responsibly, and honor 429 or 503 retry guidance so capacity remains available to everyone." + } +
++ { + "Contact us before launch. If your organization expects to consume a meaningful share of the hosted capacity, we ask it to help fund server expansion, monitoring, and security for the ecosystem." + } +
++ { + "Self-host the MIT-licensed server for predictable capacity and operational control. Sponsorship supports the shared service; it does not automatically include dedicated resources or an SLA." + } +
++ { + "For capacity planning or a separate written service agreement, contact " + } + + hyo@hyo.dev + + {" before your production launch."} +