Billing

Usage tracking and subscription management

Overview

The Billing resource provides usage tracking, Stripe checkout/portal integration, and metered billing. The Settings resource manages user preferences, sessions, and account security. The Notifications resource handles push token registration.

Billing (r.billing)

Methods

MethodDescription
get(params)Get comprehensive billing info (customer, credits, subscriptions).
getStatus(params)Get billing status for a user or organization.
getPeriods(params)Get available billing periods with usage data.
canCreateApiKey(params)Check if user/org can create API keys.
getUsage(params)Get usage summary for a billing period.
getUsageByProject(params)Get usage breakdown by project.
getUsageFromMeters(params)Get usage from Stripe meters.
getProjectUsage(projectId, params?)Get usage for a specific project.
createCheckoutSession(input)Create a Stripe Checkout session.
createPortalSession(input)Create a Stripe Billing Portal session.
ensureCustomer(params)Ensure a Stripe customer exists.
recordAiUsage(input)Record AI usage from a project.

Get billing status

1const { data: status } = await r.billing.getStatus({
2 organization_id: 'org_123',
3});
4
5console.log(status.has_stripe_account);
6console.log(status.stripe_subscription_id);
7console.log(status.status); // 'active' | 'trialing' | 'past_due' | ...
8console.log(status.has_payment_method);

Owner parameters:

All billing methods accept user_id or organization_id to scope the query:

ParameterTypeDescription
user_idstring?Scope to a user’s personal billing.
organization_idstring?Scope to an organization’s billing.

Get usage summary

1const { data: usage } = await r.billing.getUsage({
2 organization_id: 'org_123',
3 year: 2025,
4 month: 6,
5});
6
7console.log(`Sandbox compute: ${usage.sandbox_compute_hours}h`);
8console.log(`Database compute: ${usage.database_compute_hours}h`);
9console.log(`Database storage: ${usage.database_storage_gb}GB`);
10console.log(`Object storage: ${usage.storage_gb}GB`);
11console.log(`AI tokens: ${usage.ai_tokens}`);
12console.log(`AI cost: $${(usage.ai_cost_cents / 100).toFixed(2)}`);
13console.log(`Deployments: ${usage.deployment_compute_hours}h`);
14console.log(`Total: $${(usage.total_cost_cents / 100).toFixed(2)}`);
15
16// Line items
17for (const item of usage.line_items) {
18 console.log(` ${item.name}: ${item.quantity} ${item.unit} = $${item.total_cost.toFixed(2)}`);
19}

Get usage by project

1const { data: projects } = await r.billing.getUsageByProject({
2 organization_id: 'org_123',
3 year: 2025,
4 month: 6,
5});
6
7for (const p of projects) {
8 console.log(`${p.project_name}:`);
9 console.log(` Sandbox: ${p.sandbox_compute_hours}h`);
10 console.log(` AI tokens: ${p.ai_tokens}`);
11}

Get specific project usage

1const { data: items } = await r.billing.getProjectUsage('proj_123', {
2 from: '2025-06-01',
3 to: '2025-06-30',
4});
5
6for (const item of items) {
7 console.log(`${item.item}: ${item.units} ${item.unit_type}`);
8}

Available billing periods

1const { data: { periods } } = await r.billing.getPeriods({
2 organization_id: 'org_123',
3});
4
5for (const period of periods) {
6 console.log(`${period.label} (${period.year}-${period.month})`);
7}

Check API key creation eligibility

1const { data: { can_create } } = await r.billing.canCreateApiKey({
2 organization_id: 'org_123',
3});
4
5if (!can_create) {
6 console.log('Add a payment method to create API keys');
7}

Stripe Checkout (add payment method)

1const { data: checkout } = await r.billing.createCheckoutSession({
2 organization_id: 'org_123',
3 return_url: 'https://myapp.com/billing',
4});
5
6// Redirect user to checkout.url
7console.log('Checkout URL:', checkout.url);
8console.log('Session ID:', checkout.session_id);

Stripe Billing Portal

1const { data: portal } = await r.billing.createPortalSession({
2 organization_id: 'org_123',
3 return_url: 'https://myapp.com/billing',
4});
5
6// Redirect user to portal.url for managing subscriptions
7console.log('Portal URL:', portal.url);

Ensure Stripe customer

Idempotently create a Stripe customer for a user or organization.

1const { data: customer } = await r.billing.ensureCustomer({
2 organization_id: 'org_123',
3});
4
5console.log(customer.stripe_customer_id);
6console.log(customer.is_new); // true if newly created

Record AI usage

Record AI token usage from a project for metered billing.

1await r.billing.recordAiUsage({
2 project_id: 'proj_123',
3 input_tokens: 1500,
4 output_tokens: 800,
5 reasoning_tokens: 200,
6 cost_cents: 0.05,
7 provider_model: 'anthropic/claude-sonnet-4',
8});

Settings (r.settings)

Methods

MethodDescription
getPreferences()Get user preferences.
updateNotifications(input)Update notification channels.
updatePrivacy(input)Update privacy settings.
updateAppearance(input)Update appearance settings.
listSessions()List active sessions.
revokeSession(id)Revoke a session.
revokeAllSessions()Revoke all sessions.
changePassword(input)Change password.
requestEmailChange(input)Request email change.
verifyEmailChange(token)Verify email change.
requestDeletion(input?)Request account deletion.
cancelDeletion()Cancel account deletion.
getDeletionStatus()Get deletion status.
getLoginHistory(params?)Get login history.

Get and update preferences

1const { data: prefs } = await r.settings.getPreferences();
2
3console.log('Notifications:', prefs.notifications);
4// { in_app: true, push: true, email: true }
5
6console.log('Privacy:', prefs.privacy);
7// { profile_visibility: 'public', show_email: false, show_location: true }
8
9console.log('Appearance:', prefs.appearance);
10// { theme: 'system', timezone: null, locale: null }
11
12// Update notifications
13await r.settings.updateNotifications({
14 push: true,
15 email: false,
16});
17
18// Update privacy
19await r.settings.updatePrivacy({
20 profile_visibility: 'network',
21 show_email: false,
22});
23
24// Update appearance
25await r.settings.updateAppearance({
26 theme: 'dark',
27 timezone: 'America/New_York',
28});

Session management

1// List active sessions
2const { data: sessions } = await r.settings.listSessions();
3
4for (const s of sessions) {
5 console.log(`${s.user_agent} — ${s.ip_address}`);
6 console.log(` Current: ${s.is_current} — Expires: ${s.expires_at}`);
7}
8
9// Revoke a specific session
10await r.settings.revokeSession('session_123');
11
12// Revoke all sessions (nuclear option)
13await r.settings.revokeAllSessions();

Password management

1await r.settings.changePassword({
2 current_password: 'oldPassword123',
3 new_password: 'newSecurePassword456',
4});

Email change

1// Request change
2const { data: result } = await r.settings.requestEmailChange({
3 new_email: 'newemail@example.com',
4 password: 'currentPassword123',
5});
6
7console.log(result.message);
8
9// Verify with token (from email)
10await r.settings.verifyEmailChange('verification_token_from_email');

Account deletion

1// Request deletion
2const { data: deletion } = await r.settings.requestDeletion({
3 password: 'currentPassword123',
4 confirm_text: 'DELETE MY ACCOUNT',
5 reason: 'No longer using the service',
6});
7
8console.log(`Scheduled for: ${deletion.scheduled_at}`);
9
10// Check status
11const { data: status } = await r.settings.getDeletionStatus();
12console.log(`Requested: ${status.requested}`);
13console.log(`Grace period ends: ${status.grace_period_ends}`);
14
15// Cancel within grace period
16await r.settings.cancelDeletion();

Login history

1const { data: history } = await r.settings.getLoginHistory({ limit: 10 });
2
3for (const entry of history) {
4 console.log(`${entry.created_at} — ${entry.ip_address} — ${entry.success ? 'OK' : 'FAILED'}`);
5}

Notifications (r.notifications)

Methods

MethodDescription
registerToken(input)Register a push notification token.
unregisterToken(token)Unregister a push notification token.

Register push token

1await r.notifications.registerToken({
2 token: 'ExponentPushToken[abc123...]',
3 platform: 'expo',
4 device_id: 'unique-device-id',
5});

Input fields:

FieldTypeRequiredDescription
tokenstringYesPush notification token.
platform'expo' | 'fcm' | 'apns'YesPush provider platform.
device_idstring?NoUnique device identifier.

Unregister push token

Call this on sign out to stop sending push notifications to a device.

1await r.notifications.unregisterToken('ExponentPushToken[abc123...]');