MeetingRouter

Version Selection Guide

@meeting-baas/sdk - Client API & Bridge / version-selection

Version Selection Guide

This guide explains how to choose between v1 and v2 API versions and how the SDK handles version selection.

API Versions Overview

The Meeting BaaS SDK supports two API versions:

  • v1: The original API (default for backward compatibility)
  • v2: The new API with improved error handling and additional features

Selecting a Version

Default (v1)

If no version is specified, the client defaults to v1:

import { createBaasClient } from "@meeting-baas/sdk";

// Defaults to v1
const client = createBaasClient({
  api_key: "your-api-key"
});

// Only v1 methods available
await client.joinMeeting({ ... });

Explicit v1

Explicitly specify v1:

const client = createBaasClient({
  api_key: "your-api-key",
  api_version: "v1"
});

v2

To use v2 API, set api_version to "v2":

const client = createBaasClient({
  api_key: "your-api-key",
  api_version: "v2"
});

// Only v2 methods available
await client.createBot({ ... });

Type-Safe Version Selection

TypeScript automatically infers the available methods based on api_version:

// v1 client
const v1Client = createBaasClient({
  api_key: "key",
  api_version: "v1"
});

v1Client.joinMeeting({ ... });  // ✅ Available
v1Client.createBot({ ... });    // ❌ Type error

// v2 client
const v2Client = createBaasClient({
  api_key: "key",
  api_version: "v2"
});

v2Client.createBot({ ... });    // ✅ Available
v2Client.joinMeeting({ ... });  // ❌ Type error

Version Comparison

Method Names

Featurev1 Methodv2 Method
Create botjoinMeeting()createBot()
Stop botleaveMeeting()stopBot()
Get bot datagetMeetingData()getBot()
Delete bot datadeleteBotData()deleteBotData()
Batch create❌ Not availablebatchCreateBots()
Batch stop❌ Not availablebatchStopBots()
Batch get❌ Not availablebatchGetBots()

Response Formats

v1 API:

type ApiResponse\<T\> =
  | { success: true; data: T; error?: never }
  | { success: false; error: ZodError | Error; data?: never }

v2 API:

type ApiResponseV2\<T\> =
  | { success: true; data: T; error?: never }
  | {
      success: false;
      error: string;
      code: string;
      statusCode: number;
      details: unknown | null;
      data?: never
    }

Error Handling

v1:

const result = await v1Client.joinMeeting({ ... });

if (!result.success) {
  if (result.error instanceof ZodError) {
    // Validation error
  } else {
    // API error
  }
}

v2:

const result = await v2Client.createBot({ ... });

if (!result.success) {
  // Structured error with code
  console.error(result.code);
  console.error(result.error);
}

When to Use Each Version

Use v1 When:

  • You have existing code using v1 API
  • You need backward compatibility
  • You're not ready to migrate yet
  • Your application is in maintenance mode

Use v2 When:

  • Starting a new project
  • You need batch operations
  • You want better error handling
  • You need webhook type safety
  • You want the latest features

Migration Path

Gradual Migration

Run both versions side-by-side:

const v1Client = createBaasClient({
  api_key: process.env.API_KEY!,
  api_version: "v1"
});

const v2Client = createBaasClient({
  api_key: process.env.API_KEY!,
  api_version: "v2"
});

// Use v2 for new features
await v2Client.createBot({ ... });

// Keep v1 for legacy code
await v1Client.joinMeeting({ ... });

Feature Flag Pattern

const USE_V2_API = process.env.USE_V2_API === "true";

const client = createBaasClient({
  api_key: process.env.API_KEY!,
  api_version: USE_V2_API ? "v2" : "v1"
});

Abstraction Layer

interface BotService {
  createBot(meetingUrl: string, botName: string): Promise<string>;
}

class V1BotService implements BotService {
  constructor(private client: V1Client) {}

  async createBot(meetingUrl: string, botName: string) {
    const result = await this.client.joinMeeting({
      meeting_url: meetingUrl,
      bot_name: botName,
      reserved: true
    });

    if (!result.success) {
      throw new Error(result.error.message);
    }

    return result.data.bot_id;
  }
}

class V2BotService implements BotService {
  constructor(private client: V2Client) {}

  async createBot(meetingUrl: string, botName: string) {
    const result = await this.client.createBot({
      meeting_url: meetingUrl,
      bot_name: botName
    });

    if (!result.success) {
      throw new Error(result.error);
    }

    return result.data.bot_id;
  }
}

// Factory
function createBotService(): BotService {
  const useV2 = process.env.USE_V2_API === "true";

  if (useV2) {
    const client = createBaasClient({
      api_key: process.env.API_KEY!,
      api_version: "v2"
    });
    return new V2BotService(client);
  } else {
    const client = createBaasClient({
      api_key: process.env.API_KEY!,
      api_version: "v1"
    });
    return new V1BotService(client);
  }
}

Type Definitions

Client Type Inference

The SDK uses conditional types to provide correct method signatures:

import type { createBaasClient } from "@meeting-baas/sdk";

// Inferred as v1 client type
type V1Client = ReturnType<typeof createBaasClient<"v1">>;

// Inferred as v2 client type
type V2Client = ReturnType<typeof createBaasClient<"v2">>;

Importing Version-Specific Types

// v1 types
import type {
  JoinRequest,
  JoinResponse,
  LeaveRequest
} from "@meeting-baas/sdk";

// v2 types (using V2 namespace)
import type { V2 } from "@meeting-baas/sdk";

type CreateBotRequest = V2.CreateBotRequest;
type CreateBotResponse = V2.CreateBotResponse;

Testing with Multiple Versions

Parallel Tests

describe("Bot operations", () => {
  describe("v1 API", () => {
    const client = createBaasClient({
      api_key: TEST_API_KEY,
      api_version: "v1"
    });

    it("should join meeting", async () => {
      const result = await client.joinMeeting({ ... });
      expect(result.success).toBe(true);
    });
  });

  describe("v2 API", () => {
    const client = createBaasClient({
      api_key: TEST_API_KEY,
      api_version: "v2"
    });

    it("should create bot", async () => {
      const result = await client.createBot({ ... });
      expect(result.success).toBe(true);
    });
  });
});

Parameterized Tests

describe.each([
  ["v1", "joinMeeting"],
  ["v2", "createBot"]
])("%s API", (version, methodName) => {
  const client = createBaasClient({
    api_key: TEST_API_KEY,
    api_version: version as "v1" | "v2"
  });

  it(`should ${methodName}`, async () => {
    // Test implementation
  });
});

Version-Specific Features

v1 Exclusive Features

  • reserved parameter for bot creation
  • Backward-compatible error format

v2 Exclusive Features

  • Batch operations (batchCreateBots, batchStopBots, batchGetBots)
  • Structured error codes
  • Webhook type safety (via V2 namespace)
  • Improved status tracking

Best Practices

  1. Choose one version per project: Don't mix versions in the same code path

  2. Use v2 for new projects: Take advantage of improved features

  3. Plan migration: If using v1, plan to migrate to v2

  4. Test both versions: During migration, test both versions

  5. Use type inference: Let TypeScript infer the correct types

  6. Document version choice: Make it clear which version you're using

  7. Environment configuration: Make version configurable via environment

// .env
MEETING_BAAS_API_VERSION=v2

// config.ts
const client = createBaasClient({
  api_key: process.env.MEETING_BAAS_API_KEY!,
  api_version: (process.env.MEETING_BAAS_API_VERSION as "v1" | "v2") || "v1"
});

Decision Matrix

RequirementRecommended Version
New projectv2
Need batch operationsv2
Need structured errorsv2
Need webhook typesv2
Legacy codebasev1
Maintenance modev1
Planning to migratev1 → v2

Complete Example

// config/meeting-baas.ts
import { createBaasClient } from "@meeting-baas/sdk";

function getApiVersion(): "v1" | "v2" {
  const version = process.env.MEETING_BAAS_API_VERSION;

  if (version === "v2") return "v2";
  if (version === "v1") return "v1";

  // Default to v2 for new installations
  // Use v1 if MEETING_BAAS_LEGACY=true
  return process.env.MEETING_BAAS_LEGACY === "true" ? "v1" : "v2";
}

export const client = createBaasClient({
  api_key: process.env.MEETING_BAAS_API_KEY!,
  api_version: getApiVersion()
});

console.log(`Using Meeting BaaS ${getApiVersion()} API`);

On this page