Skip to content

SDK API Reference

Initializes the SDK, loads or creates an anonymous ID, queues the initial pageview, and starts the event flush timer.

Calls GET /api/v1/access/check with the URL, userId, and anonymousId.

  • if denied and onPaywall is set, the callback runs
  • if denied and onPaywall is not set, the built-in paywall is shown
  • on error, the SDK returns { granted: true, reason: 'error_fallback' }

Sets the current userId for future access checks and events.

Clears userId and falls back to the browser’s stored anonymous ID.

Queues a custom event for batched delivery.

Queues a pageview event and automatically includes url, path, title, and referrer.

Renders the built-in paywall UI for a supplied access result.

Removes the built-in paywall from the DOM.

Returns the current SDK config or null before initialization.

Register a new customer. Stores tokens in localStorage and fires auth change listeners. Returns an AuthResult.

Log in an existing customer. Stores tokens in localStorage and fires auth change listeners. Returns an AuthResult.

Revoke the refresh token on the server and clear all stored tokens. Fires auth change listeners with null.

Get the current customer’s profile from the server. Automatically refreshes the access token if expired. Returns CustomerProfile | null.

Check if the customer has stored tokens (synchronous, no network request). Returns boolean.

Get the stored customer info from localStorage without a network request. Returns AuthCustomer | null.

Get a valid access token, refreshing if necessary. Used internally by checkAccess(). Returns string | null.

Register a callback that fires whenever the auth state changes (login, logout, token refresh). Returns an unsubscribe function.

const unsubscribe = onAuthChange((customer) => {
if (customer) {
console.log('Logged in as', customer.email);
} else {
console.log('Logged out');
}
});

Create a Stripe Checkout session and redirect the browser. Requires the customer to be logged in. Uses the JWT Bearer token with a pk_ key.

await checkout({
priceId: 'latch-price-uuid',
successUrl: 'https://yoursite.com/welcome',
cancelUrl: 'https://yoursite.com/pricing',
});

Options: priceId (required), successUrl (optional), cancelUrl (optional). Returns CheckoutResult.

Open the Stripe Customer Portal for subscription self-service. Requires the customer to be logged in and have a Stripe customer record.

await openPortal({ returnUrl: 'https://yoursite.com/account' });

Options: returnUrl (optional, defaults to current page). Returns PortalResult.

Get the current customer’s active subscription. Returns SubscriptionInfo | null.

const sub = await getSubscription();
if (sub) console.log(sub.status, sub.currentPeriodEnd);
interface LatchConfig {
apiKey: string;
apiUrl?: string;
userId?: string;
anonymousId?: string;
onPaywall?: (result: AccessResult) => void;
onCheckout?: (productIds: string[]) => void;
paywallSelector?: string;
debug?: boolean;
}
FieldDescription
apiKeyPublishable key
apiUrlAPI base URL
userIdKnown reader ID
anonymousIdOverride the browser-stored anonymous ID
onPaywallCustom denied-access handler
onCheckoutBuilt-in Subscribe-button handler
paywallSelectorTarget for inline paywalls
debugEnables console logs
interface AccessResult {
granted: boolean;
reason?: string;
paywallRule?: {
id: string;
type: string;
action: {
productIds: string[];
message?: string;
meterLimit?: number;
template?: string;
};
};
meterRemaining?: number;
}

Current reason values returned by the implementation are subscribed, free_content, metered_remaining, registered, and error_fallback.

interface AuthResult {
accessToken: string;
refreshToken: string;
expiresAt: number;
customer: AuthCustomer;
}
interface AuthCustomer {
id: string;
email: string;
name: string | null;
}
interface CustomerProfile {
id: string;
email: string;
name: string | null;
customAttributes: Record<string, unknown>;
createdAt: string;
}
interface CheckoutOptions {
priceId: string;
successUrl?: string;
cancelUrl?: string;
}
interface CheckoutResult {
sessionId: string;
url: string;
}
interface PortalResult {
url: string;
}
interface SubscriptionInfo {
id: string;
priceId: string;
status: string;
cancelAtPeriodEnd: boolean;
currentPeriodStart: string | null;
currentPeriodEnd: string | null;
cancelledAt: string | null;
createdAt: string;
}