Skip to content

Plans

Every tenant is on a plan. The Plan enum has three values:

FREE_TRIAL | PRO | ENTERPRISE

A self-serve signup provisions on FREE_TRIAL. (The database column default is PRO — that's the legacy value backfilled onto tenants created by hand before self-serve existed; new self-serve tenants are explicitly set to FREE_TRIAL at approval.)

Limits

Limits live in code (PLAN_LIMITS) and are surfaced to merchants at GET /api/v1/merchant/limits (usage + cap per metric).

MetricFREE_TRIALPROENTERPRISE
Catalog items25500unlimited
Public API calls / UTC day1,00010,000unlimited
Storage100 MiB1 GiBunlimited
Staff seats15unlimited
Storefronts15unlimited

Enforcement and error responses

Both FREE_TRIAL and PRO enforce their metered limits. ENTERPRISE has no cap on these metrics. Resource limits and API request allowances use different responses:

LimitEnforcementResponse when exceeded
Catalog itemsBefore an addition to the non-archived catalog count, including create or restore402 with code: "LIMIT_EXCEEDED"
StorageWhen minting a signed upload URL and again against the actual object size on image confirmation402 with code: "LIMIT_EXCEEDED"
Staff seatsBefore inviting a teammate402 with code: "LIMIT_EXCEEDED"
Public API callsPer tenant, on metered public requests429 with code: "RATE_LIMIT_EXCEEDED"

The API allowance uses a fixed UTC day, resetting at UTC midnight, rather than a rolling 24-hour window. Its 429 includes details.resetsAt, details.retryAfterSeconds, and a matching Retry-After header. Respect that wait before another request; a quota refusal is not a resource-limit 402.

Resource caps reject additions that would exceed the limit; they do not delete existing data. Concurrent additions can pass their checks before either write finishes, so a cap is not an atomic reservation guarantee. Once usage is over the cap, further additions are blocked until usage is reduced or the cap changes. The storefronts cap remains forward-looking and is not enforced on any plan.

Staging addition: included hosted-page allowance

The staging contract also meters calls from cartonium-hosted pages within the total API allowance: 100 per UTC day on FREE_TRIAL, 1,000 on PRO, and unlimited on ENTERPRISE. These are included calls, not an extra allowance. Exhausting either ceiling returns 429; a hosted-allowance refusal includes details.limitKey: "hostedApiCallsPerDay".

In that contract, GET /merchant/limits reports limits.hostedApiCallsPerDay, usage.hostedApiCallsToday, and hostedApiApplicable. The applicability flag describes the current checkout mode; false does not erase previously recorded hosted usage. This staging addition is separate from the existing public API allowance above.

Platform billing

Platform billing is E7: a tenant pays cartonium for its SaaS plan. Shopper subscriptions are E5: a customer pays a tenant through that tenant's connected payment account. These have separate billing identities, credentials and lifecycles.

The contracts below are implemented on staging. Their presence in the API reference does not establish Production availability or enable billing for an environment. Published prices, provider readiness and the organization's current billing state still determine which actions can run.

Merchant billing endpoints require an authenticated merchant bearer token, x-organization-slug, and an Owner or Admin membership in that organization. Shopper sessions and storefront API keys do not authorize these operations.

Storefront Sandbox selection does not isolate platform billing. The API deployment and the payment provider's test/live mode are separate; a storefront Sandbox header does not select payment test mode.

GET /api/v1/public/plan-pricing is an anonymous, organization-independent projection of published, sellable CURRENT plan prices. Missing prices are omitted; the result can be empty. Use returned currency, unitAmount (minor units) and opaque quoteId when displaying an offer. Purchase requests revalidate those terms; cached pricing is not authority to charge or grant access.

The implemented endpoint families are distinct:

FamilyContract
/api/v1/merchant/platform-billingRead the current provider-subscription billing state.
…/addressRead or update the billing address and its usability. A successful update does not prove provider synchronization completed.
…/subscribe, …/resume-paymentExisting provider-subscription purchase and exact invoice recovery.
…/payment-method, …/payment-method/confirmStart card replacement for an existing provider subscription, then verify the successful setup and apply that card to the subscription.
…/invoicesRead cursor-paged invoice history for the existing provider subscription. Returned hosted invoice/PDF URLs are credentials: do not log them or put them in shared caches.
…/plan-change/*, …/cancel, …/reactivateProvider-subscription changes and period-end cancellation controls.
…/purchases/*Local first-purchase quotes, review, consent, method setup, initial payment, recovery and local invoices.
…/agreements/*Local recurring agreements, period-end cancellation intent and exact renewal recovery.

Existing provider subscriptions retain their matching contracts. resume-payment recovers an existing INCOMPLETE or PAST_DUE invoice without adopting a new public offer; reactivate reverses a scheduled cancellation. Neither is a replacement first purchase. The local purchase/agreement family does not automatically migrate existing subscriptions.

The local first-purchase request currently supports positive-price USD pro with monthly or yearly cadence. A quote, recurring-use consent, verified method setup, initial payment and committed activation are separate facts. Read returned activation state and the agreement's currentPlan; a browser redirect, saved method or historical payment success does not establish current paid access. ACTIVATION_HELD does not grant new paid access.

Preserve the original purchase, preparation and quote operation keys after a lost begin response. Continue using the exact returned references, fingerprints and generations for review, consent and recovery. Re-read retained state after a conflict; never replace a payment whose outcome is uncertain. Provider readiness AVAILABLE does not prove provider acceptance or authorize an action.

A returned handoff clientSecret is transient and belongs only to its exact setup or payment confirmation. Never log, persist or cache it. Retained status reads do not return that credential.

Broader local plan administration, discounts, zero-due purchases and negotiated Enterprise billing have separate implementation and activation gates. Accepted product direction does not make those shapes supported by these purchase requests, change the current limits above, or announce a billing launch.

Signup

Request access through litecommerce.io. Enterprise requests are reviewed by the cartonium team.