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
| 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
1 const { data: status } = await r.billing.getStatus({ 2 organization_id: 'org_123', 3 }); 4 5 console.log(status.has_stripe_account); 6 console.log(status.stripe_subscription_id); 7 console.log(status.status); // 'active' | 'trialing' | 'past_due' | ... 8 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
1 const { data: usage } = await r.billing.getUsage({ 2 organization_id: 'org_123', 3 year: 2025, 4 month: 6, 5 }); 6 7 console.log(`Sandbox compute: ${usage.sandbox_compute_hours}h`); 8 console.log(`Database compute: ${usage.database_compute_hours}h`); 9 console.log(`Database storage: ${usage.database_storage_gb}GB`); 10 console.log(`Object storage: ${usage.storage_gb}GB`); 11 console.log(`AI tokens: ${usage.ai_tokens}`); 12 console.log(`AI cost: $${(usage.ai_cost_cents / 100).toFixed(2)}`); 13 console.log(`Deployments: ${usage.deployment_compute_hours}h`); 14 console.log(`Total: $${(usage.total_cost_cents / 100).toFixed(2)}`); 15 16 // Line items 17 for (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
1 const { data: projects } = await r.billing.getUsageByProject({ 2 organization_id: 'org_123', 3 year: 2025, 4 month: 6, 5 }); 6 7 for (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
1 const { data: items } = await r.billing.getProjectUsage('proj_123', { 2 from: '2025-06-01', 3 to: '2025-06-30', 4 }); 5 6 for (const item of items) { 7 console.log(`${item.item}: ${item.units} ${item.unit_type}`); 8 }
Available billing periods
1 const { data: { periods } } = await r.billing.getPeriods({ 2 organization_id: 'org_123', 3 }); 4 5 for (const period of periods) { 6 console.log(`${period.label} (${period.year}-${period.month})`); 7 }
Check API key creation eligibility
1 const { data: { can_create } } = await r.billing.canCreateApiKey({ 2 organization_id: 'org_123', 3 }); 4 5 if (!can_create) { 6 console.log('Add a payment method to create API keys'); 7 }
Stripe Checkout (add payment method)
1 const { 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 7 console.log('Checkout URL:', checkout.url); 8 console.log('Session ID:', checkout.session_id);
Stripe Billing Portal
1 const { 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 7 console.log('Portal URL:', portal.url);
Ensure Stripe customer
Idempotently create a Stripe customer for a user or organization.
1 const { data: customer } = await r.billing.ensureCustomer({ 2 organization_id: 'org_123', 3 }); 4 5 console.log(customer.stripe_customer_id); 6 console.log(customer.is_new); // true if newly created
Record AI usage
Record AI token usage from a project for metered billing.
1 await 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
| 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
1 const { data: prefs } = await r.settings.getPreferences(); 2 3 console.log('Notifications:', prefs.notifications); 4 // { in_app: true, push: true, email: true } 5 6 console.log('Privacy:', prefs.privacy); 7 // { profile_visibility: 'public', show_email: false, show_location: true } 8 9 console.log('Appearance:', prefs.appearance); 10 // { theme: 'system', timezone: null, locale: null } 11 12 // Update notifications 13 await r.settings.updateNotifications({ 14 push: true, 15 email: false, 16 }); 17 18 // Update privacy 19 await r.settings.updatePrivacy({ 20 profile_visibility: 'network', 21 show_email: false, 22 }); 23 24 // Update appearance 25 await r.settings.updateAppearance({ 26 theme: 'dark', 27 timezone: 'America/New_York', 28 });
Session management
1 // List active sessions 2 const { data: sessions } = await r.settings.listSessions(); 3 4 for (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 10 await r.settings.revokeSession('session_123'); 11 12 // Revoke all sessions (nuclear option) 13 await r.settings.revokeAllSessions();
Password management
1 await r.settings.changePassword({ 2 current_password: 'oldPassword123', 3 new_password: 'newSecurePassword456', 4 });
Email change
1 // Request change 2 const { data: result } = await r.settings.requestEmailChange({ 3 new_email: 'newemail@example.com', 4 password: 'currentPassword123', 5 }); 6 7 console.log(result.message); 8 9 // Verify with token (from email) 10 await r.settings.verifyEmailChange('verification_token_from_email');
Account deletion
1 // Request deletion 2 const { data: deletion } = await r.settings.requestDeletion({ 3 password: 'currentPassword123', 4 confirm_text: 'DELETE MY ACCOUNT', 5 reason: 'No longer using the service', 6 }); 7 8 console.log(`Scheduled for: ${deletion.scheduled_at}`); 9 10 // Check status 11 const { data: status } = await r.settings.getDeletionStatus(); 12 console.log(`Requested: ${status.requested}`); 13 console.log(`Grace period ends: ${status.grace_period_ends}`); 14 15 // Cancel within grace period 16 await r.settings.cancelDeletion();
Login history
1 const { data: history } = await r.settings.getLoginHistory({ limit: 10 }); 2 3 for (const entry of history) { 4 console.log(`${entry.created_at} — ${entry.ip_address} — ${entry.success ? 'OK' : 'FAILED'}`); 5 }
Notifications (r.notifications)
Methods
| Method | Description |
|---|---|
registerToken(input) | Register a push notification token. |
unregisterToken(token) | Unregister a push notification token. |
Register push token
1 await r.notifications.registerToken({ 2 token: 'ExponentPushToken[abc123...]', 3 platform: 'expo', 4 device_id: 'unique-device-id', 5 });
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.
1 await r.notifications.unregisterToken('ExponentPushToken[abc123...]');