BuildBaseBuildBase

Overview

Node.js SDK for backend operations — usage recording, credit consumption, notifications, and more.

The server SDK lets you call BuildBase from your backend — record usage, consume credits, check subscriptions, send notifications, and manage workspaces.

import BuildBase from '@buildbase/sdk';

const bb = BuildBase({
  serverUrl: 'https://api.console.buildbase.app',
  orgId: 'your-org-id',
  getSessionId: async () => {
    const cookies = await getCookies();
    return cookies.get('bb-session')?.value ?? null;
  },
});

Common patterns

Record usage and enforce quotas

export async function POST(req) {
  const usage = await bb.usage.record(workspaceId, {
    quotaSlug: 'api-calls',
    quantity: 1,
    idempotencyKey: req.headers.get('x-request-id'),
  });

  if (usage.available <= 0) {
    return Response.json({ error: 'Quota exceeded' }, { status: 429 });
  }

  return Response.json({ remaining: usage.available });
}

Consume credits

try {
  await bb.credits.consume(workspaceId, {
    amount: 10,
    description: 'AI generation',
  });
} catch (err) {
  if (err.code === 'INSUFFICIENT_CREDITS') {
    return Response.json({ error: 'Not enough credits' }, { status: 402 });
  }
}

Check subscription

const { subscription, plan } = await bb.subscription.get(workspaceId);

if (!subscription || subscription.subscriptionStatus !== 'active') {
  return Response.json({ error: 'Subscription required' }, { status: 403 });
}

Send notifications

await bb.notification.send(workspaceId, 'comment-added', userId, {
  title: 'New comment',
  message: 'Someone commented on your post.',
  url: '/posts/123',
});

Background jobs with withSession()

In API routes, getSessionId reads the session from the request. For background jobs or cron tasks with no request context, use withSession():

const api = bb.withSession(serviceAccountSessionId);

await api.credits.consume(workspaceId, { amount: 50 });
await api.notification.send(workspaceId, 'job-completed');

Method reference

bb.subscription

MethodParametersReturnsDescription
get(workspaceId)string{ subscription, plan, planVersion, group, groupVersion }Get active subscription and plan details
checkout(workspaceId, options)string, { planVersionId, billingInterval?, currency?, successUrl?, cancelUrl? }{ type, checkoutUrl, sessionId }Create a Stripe Checkout session. Redirect to checkoutUrl when type is checkout; trial_started and existing need no redirect
update(workspaceId, options)string, { planVersionId, billingInterval?, successUrl?, cancelUrl? }Updated subscriptionChange plan (upgrade/downgrade with proration)
cancel(workspaceId)stringSame shape as get()Cancel at period end
resume(workspaceId)stringSame shape as get()Reverse a pending cancellation
getBillingPortalUrl(workspaceId, returnUrl?)string, string?{ url }Stripe billing portal link

bb.credits

MethodParametersReturnsDescription
getBalance(workspaceId)string{ available, totalGranted, totalConsumed, totalExpired, totalRefunded }Current credit balance
consume(workspaceId, options)string, { amount, description?, idempotencyKey? }{ success, consumed, balanceAfter }Deduct credits. Throws INSUFFICIENT_CREDITS (402) if balance too low
purchase(workspaceId, options)string, { creditPackageId, currency?, successUrl, cancelUrl }{ sessionId, url } — Stripe Checkout URLBuy a credit package
getPackages(workspaceId)stringCreditPackage[]List available credit packages
getPublicPackages(){ packages, notes? }List credit packages without auth (for public store pages)
getTransactions(workspaceId, query?)string, { type?, page?, limit? }?{ docs, totalDocs, page, totalPages, ... } — paginatedCredit history (purchases, consumption, grants)
getExpiring(workspaceId, days?)string, number?{ days, expiringCredits, buckets }Credits expiring within days (default 7)

bb.usage

MethodParametersReturnsDescription
record(workspaceId, options)string, { quotaSlug, quantity, idempotencyKey? }{ used, consumed, included, available, overage, billedAsync }Record usage against a quota
recordBatch(workspaceId, options)string, { items: Array<{ quotaSlug, quantity, idempotencyKey? }> } (max 100){ success, total, succeeded, failed, results }Record multiple quota events at once
getQuota(workspaceId, slug)string, string{ quotaSlug, consumed, included, available, overage, allowOverage }Get current usage for one quota
getAll(workspaceId)string{ quotas } — status keyed by quota slugGet all quota usage

bb.workspace

MethodParametersReturnsDescription
list()Workspace[]All workspaces for the current user
get(workspaceId)stringWorkspaceGet workspace by ID
create(options){ name, image? }WorkspaceCreate a new workspace
update(workspaceId, options)string, { name?, image? }WorkspaceUpdate workspace details (accepts partial fields)
delete(workspaceId)string{ success }Delete a workspace

bb.users

MethodParametersReturnsDescription
list(workspaceId)stringWorkspaceUser[]List workspace members
invite(workspaceId, email, role)string, string, string{ userId, workspace, message }Invite a user by email
remove(workspaceId, userId)string, string{ userId, workspace, message }Remove a member
updateRole(workspaceId, userId, role)string, string, string{ userId, workspace, message }Change a member's role

bb.notification

MethodParametersReturnsDescription
send(workspaceId, event, userId?, data?)string, string, string?, object?{ sent, channels, notifiedCount?, reason? }Send email + push notification for an event. Omit userId to notify all members

bb.permissions

Both methods take an explicit userId — check any workspace member, not only the session's user.

MethodParametersReturnsDescription
check(workspaceId, userId, permission)string, string, string | string[]booleanCheck if a user has a permission (an array requires all of them)
resolve(workspaceId, userId)string, stringSet<string>Get all resolved permissions for a user

Next Steps

  • Webhooks — Handle events in your backend.
  • Quotas — Usage recording and metering.