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
| Method | Description |
|---|---|
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
const { data: status } = await r.billing.getStatus({organization_id: 'org_123',});console.log(status.has_stripe_account);console.log(status.stripe_subscription_id);console.log(status.status); // 'active' | 'trialing' | 'past_due' | ...console.log(status.has_payment_method);
Owner parameters:
All billing methods accept user_id or organization_id to scope the query:
| Parameter | Type | Description |
|---|---|---|
user_id | string? | Scope to a user’s personal billing. |
organization_id | string? | Scope to an organization’s billing. |
Get usage summary
const { data: usage } = await r.billing.getUsage({organization_id: 'org_123',year: 2025,month: 6,});console.log(`Sandbox compute: ${usage.sandbox_compute_hours}h`);console.log(`Database compute: ${usage.database_compute_hours}h`);console.log(`Database storage: ${usage.database_storage_gb}GB`);console.log(`Object storage: ${usage.storage_gb}GB`);console.log(`AI tokens: ${usage.ai_tokens}`);console.log(`AI cost: $${(usage.ai_cost_cents / 100).toFixed(2)}`);console.log(`Deployments: ${usage.deployment_compute_hours}h`);console.log(`Total: $${(usage.total_cost_cents / 100).toFixed(2)}`);// Line itemsfor (const item of usage.line_items) {console.log(` ${item.name}: ${item.quantity} ${item.unit} = $${item.total_cost.toFixed(2)}`);}
Get usage by project
const { data: projects } = await r.billing.getUsageByProject({organization_id: 'org_123',year: 2025,month: 6,});for (const p of projects) {console.log(`${p.project_name}:`);console.log(` Sandbox: ${p.sandbox_compute_hours}h`);console.log(` AI tokens: ${p.ai_tokens}`);}
Get specific project usage
const { data: items } = await r.billing.getProjectUsage('proj_123', {from: '2025-06-01',to: '2025-06-30',});for (const item of items) {console.log(`${item.item}: ${item.units} ${item.unit_type}`);}
Available billing periods
const { data: { periods } } = await r.billing.getPeriods({organization_id: 'org_123',});for (const period of periods) {console.log(`${period.label} (${period.year}-${period.month})`);}
Check API key creation eligibility
const { data: { can_create } } = await r.billing.canCreateApiKey({organization_id: 'org_123',});if (!can_create) {console.log('Add a payment method to create API keys');}
Stripe Checkout (add payment method)
const { data: checkout } = await r.billing.createCheckoutSession({organization_id: 'org_123',return_url: 'https://myapp.com/billing',});// Redirect user to checkout.urlconsole.log('Checkout URL:', checkout.url);console.log('Session ID:', checkout.session_id);
Stripe Billing Portal
const { data: portal } = await r.billing.createPortalSession({organization_id: 'org_123',return_url: 'https://myapp.com/billing',});// Redirect user to portal.url for managing subscriptionsconsole.log('Portal URL:', portal.url);
Ensure Stripe customer
Idempotently create a Stripe customer for a user or organization.
const { data: customer } = await r.billing.ensureCustomer({organization_id: 'org_123',});console.log(customer.stripe_customer_id);console.log(customer.is_new); // true if newly created
Record AI usage
Record AI token usage from a project for metered billing.
await r.billing.recordAiUsage({project_id: 'proj_123',input_tokens: 1500,output_tokens: 800,reasoning_tokens: 200,cost_cents: 0.05,provider_model: 'anthropic/claude-sonnet-4.6',});
Settings (r.settings)
Methods
| Method | Description |
|---|---|
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
const { data: prefs } = await r.settings.getPreferences();console.log('Notifications:', prefs.notifications);// { in_app: true, push: true, email: true }console.log('Privacy:', prefs.privacy);// { profile_visibility: 'public', show_email: false, show_location: true }console.log('Appearance:', prefs.appearance);// { theme: 'system', timezone: null, locale: null }// Update notificationsawait r.settings.updateNotifications({push: true,email: false,});// Update privacyawait r.settings.updatePrivacy({profile_visibility: 'network',show_email: false,});// Update appearanceawait r.settings.updateAppearance({theme: 'dark',timezone: 'America/New_York',});
Session management
// List active sessionsconst { data: sessions } = await r.settings.listSessions();for (const s of sessions) {console.log(`${s.user_agent} — ${s.ip_address}`);console.log(` Current: ${s.is_current} — Expires: ${s.expires_at}`);}// Revoke a specific sessionawait r.settings.revokeSession('session_123');// Revoke all sessions (nuclear option)await r.settings.revokeAllSessions();
Password management
await r.settings.changePassword({current_password: 'oldPassword123',new_password: 'newSecurePassword456',});
Email change
// Request changeconst { data: result } = await r.settings.requestEmailChange({new_email: 'newemail@example.com',password: 'currentPassword123',});console.log(result.message);// Verify with token (from email)await r.settings.verifyEmailChange('verification_token_from_email');
Account deletion
// Request deletionconst { data: deletion } = await r.settings.requestDeletion({password: 'currentPassword123',confirm_text: 'DELETE MY ACCOUNT',reason: 'No longer using the service',});console.log(`Scheduled for: ${deletion.scheduled_at}`);// Check statusconst { data: status } = await r.settings.getDeletionStatus();console.log(`Requested: ${status.requested}`);console.log(`Grace period ends: ${status.grace_period_ends}`);// Cancel within grace periodawait r.settings.cancelDeletion();
Login history
const { data: history } = await r.settings.getLoginHistory({ limit: 10 });for (const entry of history) {console.log(`${entry.created_at} — ${entry.ip_address} — ${entry.success ? 'OK' : 'FAILED'}`);}
Notifications (r.notifications)
Methods
| Method | Description |
|---|---|
registerToken(input) | Register a push notification token. |
unregisterToken(token) | Unregister a push notification token. |
Register push token
await r.notifications.registerToken({token: 'ExponentPushToken[abc123...]',platform: 'expo',device_id: 'unique-device-id',});
Input fields:
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Push notification token. |
platform | 'expo' | 'fcm' | 'apns' | Yes | Push provider platform. |
device_id | string? | No | Unique device identifier. |
Unregister push token
Call this on sign out to stop sending push notifications to a device.
await r.notifications.unregisterToken('ExponentPushToken[abc123...]');