Skip to main content

Server options

Pass these options to creem() in your Better Auth configuration: Webhook callback options are covered in Webhooks and access.
lib/auth.ts
testMode defaults to false. Do not pair a test API key with production mode or a production API key with test mode.

Persistence mode

Persistence is enabled unless you explicitly set persistSubscriptions: false. The plugin then:
  • adds its models and fields to the Better Auth schema;
  • associates a Creem customer ID with the signed-in user;
  • writes subscription state received through verified webhooks;
  • checks local subscription records in hasAccessGranted();
  • records whether a user has already received a trial.
After enabling persistence or upgrading to a version that changes the schema, use the command for your database workflow. The built-in Kysely adapter can apply the migration directly:
For Prisma, Drizzle, or another ORM-managed schema, generate the schema and then apply it with the ORM’s migration tooling:

Added models and fields

The creem_subscription model contains: Existing records are not automatically backfilled. cancelAtPeriodEnd may remain unset or stale until a subsequent event updates the record. Access checks use status and periodEnd. The plugin extends the Better Auth user model with:

Without persistence

Set persistSubscriptions: false when your application owns subscription storage or does not need local billing state:
No plugin schema is added: neither subscription models nor Creem user fields are registered. No plugin customer, trial, or subscription data is written. hasAccessGranted() cannot determine access in this mode, so implement access checks in your own data layer. Other endpoints can still call Creem, provided they receive or can resolve the required customer or subscription identifier. Mirror this option in your client configuration so session types do not promise fields that the server has not registered:

Custom model and column names

With persistence enabled, schema maps existing logical names to physical database names:
Field mappings are strings, not field definition objects. They rename existing models and columns; they do not add models, add fields, or change their types. The logical names in session and endpoint types stay the same. Overrides are ignored when persistence is disabled. Each server plugin instance has its own schema, so overrides do not affect other instances.

Client options

The standard Better Auth client infers the Creem endpoints from creemClient():
lib/auth-client.ts
baseURL is optional when the client calls the same origin. Use Better Auth’s client import for your framework, such as better-auth/react for React. The standard client infers Creem endpoint inputs and successful responses. With persistence enabled (the default), it also infers session.user.creemCustomerId and session.user.hadTrial. The client option persistSubscriptions must match the server option; it controls types only and cannot enable server persistence. createCreemAuthClient remains exported but is deprecated. Replace it with your framework’s standard createAuthClient while keeping creemClient() in the plugins array. See the 2.0 migration guide for response handling changes.