Billing
PickLayer meters every AI call, enforces per-user and per-org quotas, and exposes funding sources so end-users can pay for what they use. Funding can come from one of two payment surfaces:
- Stripe — credit-card subscriptions, payment-method management, overage credits, and the bulk of the end-user billing API. Used for web and Android clients.
- Apple App Store — StoreKit 2 in-app purchases verified server-side. Used for iOS clients, where Apple’s guidelines require IAP for digital goods.
The two are peers: a single billing plan can expose multiple funding modes (e.g. one Stripe price and one Apple product), and a user lands in the same funded state regardless of which path they took.
Pending lifecycle
Every AI call inserts a usage_events row with:
status = 'pending'model_code,vendorestimate_tokens_in/outestimate_costexpires_at = now() + 20 minutes
When the upstream provider responds, we update the same row with actual tokens/cost, set status to success/failed/error, and fill finalized_at. A cleanup job marks any entry whose expires_at elapsed as expired, which removes its estimate from active quotas.
Quota evaluation
Quotas are enforced before the provider call using an aggregate view that counts both finalized usage and in-flight estimates:
- User plans (
billing_plans+user_plan_assignments): requests/min, requests/day, tokens/day, monthly cost. - Application hard caps:
applications.hard_cap_*. - Organization budgets (
organizations.budget_limitifhard_cap_enabled).
Violations return 429 QUOTA with limitType, limitValue, currentValue, and retryAfterSeconds. Retry-After is also set in HTTP headers.
Usage APIs
GET /usage/summary– summarized quotas (requests today, tokens today, spend month, etc.).GET /usage/histogram?window=day&bins=30– time-series of token or cost usage.
All usage data respects the caller’s user scope; builders can use Hasura directly for org-wide dashboards.
Funding readiness
Regardless of provider, the GET /v1/billing/readiness endpoint is the single source of truth for whether a user can make billed calls. It returns funded: true/false, the active plan, the subscription block (when funded via Stripe), and cap_windows. Clients should poll it after any purchase flow to confirm activation. See the Stripe page for the full response shape.