This reference targets protocol 0.5. See version information for SDK availability and HTTP examples.
Related:Versions and integration
Keep the Server Key on your host backend. baseUrl and scope identify the App/environment; every request checks credential permissions. Each Funnel owns its evaluation mode: new Funnels default to Local, and Owners/Admins can switch to Remote in Funnel settings. One API key can call different modes. Read the target mode with createFunnelDecisionClient({baseUrl, scope, apiKey, funnelId}).configuration(): use features() or evaluateFunnelNode() for Local, and decide()/submit() for Remote. The SDK has no remoteEval override.
Related:Server API key authentication and rotation
The Invoice SDK methods listed here are available in npm 0.5.0; npm 0.4.0 does not export them. The server and database must match protocol 0.5. SDK publication and server deployment are separate.
Current exports and methods
listInvoiceTemplates({ cursor? })Permissions
billing:readRead invoice templates scoped to the App and environment.
Returns { templates }
previewInvoice({ customerId, params })Permissions
billing:writePreview invoice amounts and line items without creating a Stripe invoice.
Returns { preview }
createInvoice({ customerId, requestId, params })Permissions
billing:writeAccept a durable invoice command. Reuse requestId on retries and read the operation result.
Returns { operation }
manageInvoice({ customerId, command })Permissions
billing:writeUpdate, finalize, pay, void or reissue an invoice using a durable idempotency key.
Returns { operation }
readInvoiceOperation({ customerId, taskId })Permissions
billing:readRead the state, invoice reference or error of an asynchronous invoice command.
Returns { operation }
listInvoices({ customerId, cursor? })Permissions
billing:readRead a page of invoices for the selected Customer.
Returns { invoices }
getInvoice({ customerId, invoiceId })Permissions
billing:readRead an invoice, its line items and related operations.
Returns { invoice }
getFeatures()Permissions
features:readRead local flag definitions and remote flag keys. List groups contain hashes; remote rules stay on the server.
Returns { payload }
evaluateFeatures({ attributes, features?, customerId? })Permissions
features:readEvaluate only flags configured for server evaluation. A selected Customer supplies verified identity and stored attributes; the server records exposures. Clients cannot override the flag's evaluation location.
Returns { features, generation, expiresAt }
trackEvents({ customerId?, events })Permissions
events:writeSend up to 100 analytics events with eventUuid, timestamp, name and properties. Reuse eventUuid after a lost response. Analytics events never establish payment or authorization facts.
Returns { inserted, duplicates, rejected, skipped }
resolvePaywall({ customerId?, selector, locale, commerce, requirement? })Permissions
entitlements:readResolve the independent Paywall, pinned Offering Version and current presentation capabilities without a Funnel or purchase.
Returns { paywall }
setupPayment({ customerId, requestId, currency, makeDefault })Permissions
billing:writeCreate a standalone card setup, without a subscription, entitlement or usage billing consent.
Returns { setup }
readPaymentSetup({ customerId, setupId })Permissions
billing:readVerify the actual provider result of the original setup without duplicate charges.
Returns { setup }
listSubscriptions({ customerId?, entityId?, productId?, provider?, status?, cursor?, limit? })Permissions
billing:readPage subscriptions by provider and cursor, retaining each provider contract.
Returns { subscriptions }
listPurchases({ customerId?, entityId?, productId?, provider?, status?, cursor?, limit? })Permissions
billing:readRead verified purchase history and original amounts; history does not imply current entitlement.
Returns { purchases }
listSubscriptionConflicts({ customerId?, status?, cursor?, limit? })Permissions
billing:readRead verified purchase conflicts and the memberships blocking an exclusive main plan.
Returns { conflicts }
retrySubscriptionConflict({ customerId, orderId })Permissions
billing:writeRetry the original delivery, returning blocked if blockers remain, without another payment.
Returns { resolution }
manageSubscriptionTrial({ customerId, requestId, action, reason, ...trialParameters })Permissions
billing:writeStart, extend or end a trial; Indiana runs no-card trials, and Stripe subscription trials return execution instructions that take effect once the webhook is recorded.
Returns { trial }
readSubscriptionTrial({ customerId, operationId })Permissions
billing:readRecover the original trial operation, reconciling Stripe when needed and retaining activation evidence.
Returns { trial }
previewSubscriptionBatch({ customerId, requestId, targets })Permissions
billing:writeQuote by actual provider container; continue with the original request while ready is false.
Returns { batch }
confirmSubscriptionBatch({ customerId, batchId })Permissions
billing:writeAccept frozen targets, retaining successful groups and recovering unfinished ones; partial is not complete.
Returns { batch }
readSubscriptionBatch({ customerId, batchId })Permissions
billing:readRead each original group state without accepting a quote or issuing another provider operation.
Returns { batch }
abandonSubscriptionBatch({ customerId, batchId })Permissions
billing:writeAbandon only an unaccepted batch; submitted provider operations retain their original recovery tasks.
Returns { batch }
verifySubscriptions({ customerId })Permissions
billing:readCompare the customer's recorded products with Stripe Sandbox subscriptions (only when Indiana runs payments). Returns consistency, drift or incomplete evidence without charging or repairing.
Returns { verification }
previewRefund({ customerId, requestId, invoiceId, mode, amountMinor, entitlementAction })Permissions
billing:readQuote a refund of the customer's paid Stripe invoice: full refunds the remaining refundable amount, partial refunds amountMinor. A refund changes no plans unless entitlementAction is revoke, which also ends the plans the invoice paid for. The quote holds the amount and does not call Stripe.
Returns { quote }
refund({ customerId, operationId })Permissions
billing:writeConfirm the refund. Where Indiana runs payments it creates the Stripe refund once with your connected key; where your backend runs payments the operation returns execution instructions, and your backend refunds in Stripe with their metadata and idempotency key. The refunded amount is recorded when Stripe's refund notification arrives; retries return the same operation.
Returns { operation }
readRefund({ customerId, operationId })Permissions
billing:readRead the refund operation's status (quoted, pending, succeeded, failed, expired) without creating a refund.
Returns { operation }
readBillingInvoice({ customerId, invoiceId, after, limit })Permissions
billing:readPage through all verified invoice items with nextCursor, without charging.
Returns { detail }
readCreditStatement({ customerId, from, to, entityId?, snapshotAt, after, limit })Permissions
credits:readUp to 366 days. The first page uses null snapshotAt/after; subsequent pages retain the original snapshot and complete cursor.
Returns { statement }
previewUpdate({ customerId, requestId, membershipId, timing, change })Permissions
billing:readQuote a plan, seat or cancellation change for a membership billed by a Stripe subscription; upgrades are immediate and prorated, downgrades take effect at the end of the cycle.
Returns { quote }
update({ customerId, operationId })Permissions
billing:writeConfirm the quote: Indiana execution runs it once in Stripe; record-only mode returns the Stripe instructions for the merchant.
Returns { operation }
readSubscriptionUpdate({ customerId, operationId })Permissions
billing:readRead the change status; a booked downgrade or cancellation is scheduled until it takes effect.
Returns { operation }
manageBalanceGrant({ customerId, command })Permissions
credits:manageCreate recurring or one-time grants, adjust remaining balances, change expiry or revoke a rule with requestId and revision. Requires server credits:manage; payment facts remain immutable.
Returns { grant }
listBalanceGrants({ customerId, after, limit })Permissions
credits:readRead customer and Entity grants with available, held and spent balances. Page with nextCursor and a maximum limit of 100.
Returns { grants }
previewAttach({ customerId, entityId?, requestId, plans, provider, currency, offerId? })Permissions
billing:readSave a fixed quote for an explicit customer without initiating payment; reuse requestId on retries. Independent execution supports one Stripe or free plan, or multiple paid Stripe plans on one connection, currency and billing interval, without multi-plan trials or seats.
Returns { quote }
attach({ customerId, operationId })Permissions
billing:writeConfirm after the customer reviews and accepts the quote. Retries reuse operationId and the original order without a Funnel.
Returns { operation }
restoreNativePurchase({ customerId, requestId, provider, purchaseIntentId, productId, signedTransaction?, purchaseToken? })Permissions
billing:writeRecover the same purchase and delivery from verified store facts without issuing credits twice.
Returns { restore }
readAiPricing({ internal_feature_id })Permissions
credits:readRead current model prices and markups.
Returns { configuration }
readBalanceSource({ customerId, sourceId })Permissions
credits:readRead available, held and spent funds in the plan's current window.
Returns { balance }
adjustBalance({ customerId, command })Permissions
credits:manageAdd, subtract or set plan funds after checking expectedAvailable; retry the same requestId.
Returns { balance }
readUsage({ customerId, query })Permissions
credits:readRead capacity and actual non-consumable usage.
Returns { usage }
setUsage({ customerId, command })Permissions
credits:manageAtomically synchronize actual usage with expectedRevision, including decreases and usage above capacity.
Returns { usage }
readSubscriptionOperation({ customerId, operationId })Permissions
billing:readRecover payment and delivery for an accepted operation without creating another provider attempt.
Returns { operation }
manageBillingLimits({ customerId, command })Permissions
billing:writeThe trusted server sets customer or Entity usage limits, alerts or control: overage policies with an idempotent requestId. Overage policies contain allowed, overageLimit, skipOverageBilling and a UTC window. Entity policies override customer policies; removal restores inheritance. Customers still confirm payment consent.
Returns { controls }
getOrCreateCustomer(input)Permissions
customers:writeFind or create a customer by the host-verified externalUserId. Retries do not overwrite existing profiles; email is not identity. The optional fingerprint is a stable deduplication signal supplied by your host, such as a device identifier. The SDK does not collect it; only an environment-scoped hash is kept and the first supplied value is never replaced. Without it, trials deduplicate by Customer only. You can also reserve a customer with only an email (for example, a contract signed before sign-up). When that user signs up, calling with an externalUserId and the same email claims the reservation in place, keeping its plans and balances. Only send verified emails; otherwise someone else could claim the reservation.
Returns { customer, created }
getCustomer({ lookup }) / listCustomers(filters)Permissions
customers:readLook up an explicit id or externalUserId; listing applies current customer filters before pagination.
Returns Customer response
updateCustomer({ lookup, requestId, patch })Permissions
customers:writeUpdate supplied profile fields and attributes. Use removeAttributes to delete keys and tagChanges for tags. Submit changed fields only and retain the original requestId for retries.
Returns Customer response
createCustomerSession(customerId)Permissions
sessions:createIssue a short-lived session for the Indiana customer mapped to the host's verified login. Do not derive identity from browser parameters.
Returns { customerToken, expiresAt }
renewCustomerSession(input) / revokeCustomerSessions(input)Permissions
sessions:createRecheck host authentication before renewal or revocation. Revocation requires sessions:create; reset clears SDK memory only.
Returns Session response
createGuestToken()Generate a guest proof on your backend, retain it in an HttpOnly cookie and reuse it for creation retries.
Returns gg_gc_ token
createGuestCustomer(input) / resumeGuestSession(input) / claimGuestCustomer(input)Permissions
sessions:createGuest creation, recovery and claiming require their respective session or customers:write permissions. Derive the claimed externalUserId from verified login; authenticate before store purchases. Guest creation accepts a fingerprint. Login to an existing Customer returns switched=true: create its session and start a new Funnel. Each Customer retains its profile, device and history.
Returns Guest/session response
resolveOffering({ customerId, selector, commerce, requirement? })Permissions
entitlements:readResolve a published Offering hierarchy and per-Product availability without creating a Funnel or UI. Purchase independently through previewAttach/attach. Preserve the Offering Version and follow explicit unavailable reasons.
Returns { offering, candidates, availability, check }
checkEntitlement({ customerId, requirement, commerce?, paywallId? })Permissions
entitlements:readAvailable in npm 0.1.0 beta with a matching server deployment. Check access and recommend products without consumption or automatic payment. Derive customerId from verified host authentication.
Returns { check }
readHoldings({ customerId })Permissions
entitlements:readRead current memberships and balances. Decimal quantities remain strings and existing memberships retain their contract versions.
Returns { holdings }
readLedger({ customerId, query })Permissions
credits:readFilter all history before pagination. Preserve the entire nextCursor and clear it when filters change.
Returns { ledger }
quoteBalance({ customerId, command })Permissions
credits:readcommand.operation is quote. A quote does not spend funds or replace atomic consumption.
Returns { quote }
mutateBalance({ customerId, command })Permissions
credits:consumeConsume, reserve, confirm, release or refund at the original rate. Retain each action's original idempotencyKey and input; refunds also require credits:manage.
Returns { receipt }
trackUsage({ customerId, command })Permissions
credits:consumeConsume features mapped to eventName or a specific internal_feature_id; choose one target type. Derive the customer identity on the trusted backend, retain the original idempotencyKey and input for retries, and inspect each receipt's accepted status.
Returns { receipts }
readSeats(input) / manageSeat(input)Permissions
customers:readRead purchased capacity and assign identified members. Assignments require billing:write; billed capacity changes are confirmed through Funnel nodes.
Returns Seat response
manageUsageEntity(input) / readCreditAnalytics(input) / readUsageAnalytics(input)Permissions
credits:manageManage usage scope for a verified customer. Analytics requires credits:read; client-supplied payer identity does not authorize access.
Returns Usage entity / analytics response
submitUsageBatch(input) / readUsageBatch(input)Permissions
credits:consumePersist processing with an independent idempotent receipt per item. Reading progress requires credits:read.
Returns Batch response
grantOffer({ customerId, couponId, requestId })Permissions
offers:grantTrusted backends use offers:grant and the merchant customerId. The source Customer SDK provides claimCoupon(couponId, requestId) with offers:resolve for self-claim-enabled Coupons; Local Funnel uses the same Coupon API. Indiana checks scope, eligibility and limits. Retain requestId on retry.
Returns Offer response
recordCouponRedemption({ customerId, eventId, grantId, productVersionId, subscriptionId, occurredAt })Permissions
billing:writeAvailable in the source SDK; published0.3.1 uses the corresponding HTTP endpoint. Report after your trusted backend confirms payment with billing:write; retain eventId and all facts on retry. The merchant receipt consumes the held Grant, creates no subscription or entitlement, and does not keep Funnel waiting for payment.
Returns Merchant Coupon receipt response
AI model pricing
createConfiguredAiPricing(client, { entitlementId })Permissions
credits:readRead current model prices and markups for the App/environment. Recreate pricing after saving configuration; saved quotes are not repriced. See the AI token guide for integration and recovery.
Returns Promise<AI pricing helper>
createOpenRouterUsageClient({ openRouter, pricing, client, reasoning, context, persist, mapTokens? }) / trackOpenRouterUsage(input)Import from the separate /openrouter entry and install @openrouter/sdk in the host. Wrap chat.send, persisting actual usage and the frozen quote before atomic settlement. Recover with the original generationId, usage, quote and idempotency key without rerunning the model.
Returns OpenRouter client / persisted usage record
createAiUsageMiddleware({ pricing, client, modelId, reasoning, context, persist, mapTokens? })AI SDK v7 captures final usage for generate and streaming. context supplies a durable unique key per provider call or tool step; persist saves actual usage and the frozen quote before balance consumption. Interrupted usage is not estimated. Settlement failure is explicit; retry the original quote without rerunning the model.
Returns LanguageModelV4Middleware
createAiPricing(options?)Trusted server only. Read current model prices from Models.dev with a 15-minute cache. Configure default, provider and model markups or custom model prices. The metered entitlement must use one micro USD; a fixed credit rate converts the cost.
Returns AI pricing helper
pricing.quoteTokens({ modelId, tokens })Supply seven mutually exclusive token pools, using zero for unused pools. Freeze rates, context tier, markup, quantity and hash. Missing required prices are rejected. Explicit free prices retain real tokens in zero-cost events. Persist the original quote for job retries.
Returns Promise<AiTokenQuote>
pricing.trackTokens(client, { customerId, internal_feature_id, entityId?, idempotencyKey, quote, properties? })Permissions
credits:consumeValidate the frozen quote and record tokens and model rates in one atomic balance mutation. Reuse the quote and idempotency key for retries; refunds use the original consumption price. Supply actual usage manually or capture it with createAiUsageMiddleware.
Returns Promise<Balance mutation response>
pricing.refreshPrices()Clear the price cache so the next quote reloads prices. Saved quotes, consumption and refunds retain their original rates.
Returns void
aiTokenQuoteSchema.parse(value) / aiPriceSnapshotSchema.parse(value)Validate a persisted current quote or price snapshot without calling a model or changing a balance.
Returns Validated quote / price snapshot
Funnel and store recovery
createFunnelDecisionClient(options).submit(input) / decide(input) / read(decisionId) / reportUsed(input)Trusted backend with sessions:create and funnels:run. customer is { type: "id" } (an Indiana Customer ID) or { type: "externalUserId" } (your user ID; a missing Customer is created with the decision, needs customers:write and may carry creation-only customerData). Fix customer, Funnel and original requestId. submit returns without waiting; decide waits up to 30 seconds. Retry original input when acceptance is unknown; read the original decisionId when accepted but pending. reportUsed records a caller report without issuing or charging.
Returns Decision status / decision / usage report
createFunnelOrchestrationClient(options).signal(input) / readResults(runId)Backend sessions:create and funnels:run only. Send declared custom receipts, retaining eventId and data for retries. Acknowledgement is not consumption. Read completed task and consumed receipt results; custom receipts cannot confirm payment.
Returns Receipt acknowledgement / node results
renewFunnelRun(options, { runId, customerId })A backend with sessions:create and funnels:run renews the credential for the same identified customer without extending runExpiresAt. Browsers cannot renew it or change customer identity.
Returns Renewed run credential
createPaywallStartClient(options).start({ paywallId, requirement?, ...input })Available in npm 0.1.0 beta. With a matching server, persist original input and requestId on the backend with a customer session and explicit provider/currency. requirement is frozen for the run while retaining the authored Paywall version.
Returns FunnelRuntimeResponse
createFunnelStartClient(options).start(input)Persist the original start input and requestId. A server Key uses customer: { type: 'id' | 'externalUserId', value }; creation-only customerData requires an externalUserId reference and customers:write. Use the returned customerId to issue a session with sessions:create. Customer-credential starts name no customer. Standalone Paywall uses its own session; the old start-body customerToken is rejected.
Returns FunnelRuntimeResponse
createFunnelCampaignClient(options).decide(input) / start(input)Invoke campaigns explicitly from a trusted backend. Both decide/start use a customer reference; start requires cooldownSeconds. Frequency or in-progress suppression returns suppressed and retryAt without a fake Run. Report shown only after actual presentation. Customer and Run credentials cannot replace the server Key.
Returns FunnelDecision / FunnelCampaignStartResponse
createNativeReceiptClient(options).recover(command)Current orders only: use a backend Key plus the current Customer session through subscriptions/native/restore to submit evidence or read the accepted operation. orderId and receiptId must identify the same commercial intent. Recovery does not rely on runToken or advance an old run. Requires billing:write and funnels:run. See the native guides for store availability.
Returns NativeReceiptResponse