Skip to main content

vaults.createEnterprise

Creates a new enterprise vault and either adds an existing user as owner or creates a pending invitation for a new user.
This endpoint requires admin API credentials. It is not available to regular authenticated users.

Request

name
string
required
Display name for the vault. Minimum 1 character.
slug
string
URL-friendly identifier. Auto-generated from name if not provided. Maximum 64 characters.
color
string | null
Hex color code for UI display (e.g., #3b82f6)
defaultAdminEmail
string
required
Email address of the initial vault owner. Must be a valid email format.
const vault = await trpc.vaults.createEnterprise.mutate({
  name: "Acme Corp Vault",
  slug: "acme-corp",
  color: "#3b82f6",
  defaultAdminEmail: "[email protected]"
});

Response

id
string
required
UUID of the created vault
slug
string
required
Final slug (auto-generated if not provided in request)
name
string
required
Display name of the vault
type
literal
required
Always "enterprise"
color
string | null
required
Hex color code or null
defaultAdminEmail
string
required
Email of the initial admin
bootstrapStatus
enum
required
Indicates how the admin was onboarded:
  • membership_created: User already existed, membership created directly
  • invitation_created: User doesn’t exist yet, invitation created
invitationId
string | null
required
UUID of the invitation if bootstrapStatus is invitation_created, otherwise null

Example

import { createTRPCClient } from '@trpc/client';
import type { AppRouter } from '@better-skills/api';

const trpc = createTRPCClient<AppRouter>({
  // ... admin API client config
});

// Create vault for existing user
const vault1 = await trpc.vaults.createEnterprise.mutate({
  name: "Engineering Team",
  defaultAdminEmail: "[email protected]"
});
// {
//   id: "a1b2c3d4-...",
//   slug: "engineering-team",
//   name: "Engineering Team",
//   type: "enterprise",
//   color: null,
//   defaultAdminEmail: "[email protected]",
//   bootstrapStatus: "membership_created",
//   invitationId: null
// }

// Create vault for new user
const vault2 = await trpc.vaults.createEnterprise.mutate({
  name: "Product Team",
  slug: "product",
  color: "#10b981",
  defaultAdminEmail: "[email protected]"
});
// {
//   id: "e5f6g7h8-...",
//   slug: "product",
//   name: "Product Team",
//   type: "enterprise",
//   color: "#10b981",
//   defaultAdminEmail: "[email protected]",
//   bootstrapStatus: "invitation_created",
//   invitationId: "i9j0k1l2-..."
// }

Validation

  • Vault slugs must be unique across the system
  • Slugs are auto-normalized: lowercased, special characters replaced with hyphens
  • Invalid slugs (empty after normalization) will throw a BAD_REQUEST error
  • Duplicate slugs throw a BAD_REQUEST error with message "Vault slug already exists"

Invitation Expiry

When an invitation is created (bootstrapStatus: "invitation_created"), it expires after 14 days.

Build docs developers (and LLMs) love