Slice SDK Documentation

TypeScript SDK for integrating license validation and management into your applications.

Introduction

What is the Slice SDK and why use it?

The Slice SDK is a TypeScript library that provides a type-safe, cross-platform interface for integrating license validation and management into your applications. It simplifies API interactions and provides comprehensive error handling.

Key Features

  • Type Safe: Full TypeScript support with exported types
  • Cross-Platform: Works in both Node.js (18+) and browser environments
  • Modern: Uses native fetch API
  • Error Handling: Custom error classes with meaningful messages
  • Flexible: Configurable base URL and timeout settings

Use Cases

  • Validate user licenses in your application
  • Create and manage users programmatically
  • Assign licenses to users
  • Update license status
  • Build license-gated features

Installation

Install the SDK in your project

The Slice SDK is available as a workspace package. Since it's a private package, you'll need to install it from your workspace or configure it as a local dependency.

Using pnpm (Recommended)

pnpm add @sliceapi/sdk

Using npm

npm install @sliceapi/sdk

Using yarn

yarn add @sliceapi/sdk

Note: This is a private package. Make sure your workspace is properly configured to access the @sliceapi/sdk package.

Quick Start

Get up and running in minutes

1. Import the SDK

import { SliceClient } from '@sliceapi/sdk';

2. Initialize the Client

const client = new SliceClient('sk_live_...', {
  baseUrl: 'https://api.example.com' // Optional
});

3. Validate a License

const result = await client.validate.validate('user_123');

if (result.valid) {
  console.log('License is valid:', result.license);
  console.log('Features:', result.features);
} else {
  console.log('License invalid:', result.reason);
}

See the API Reference section for complete documentation on all available methods.

Configuration

Configure the SDK to match your environment

Constructor Options

interface SliceClientOptions {
  /**
   * Base URL for the API
   * Defaults to process.env.SLICE_API_URL or 'http://localhost:3001'
   */
  baseUrl?: string;
  
  /**
   * Request timeout in milliseconds
   * Defaults to 30000 (30 seconds)
   */
  timeout?: number;
}

Environment Variables

You can set the base URL using an environment variable:

# .env
SLICE_API_URL=https://api.example.com

API Key Setup

To get your API key:

  1. Log in to your Slice dashboard
  2. Navigate to the API Keys section
  3. Create a new API key (starts with sk_live_ or sk_test_)
  4. Copy the key and store it securely (never commit it to version control)

Security Tip: Always use environment variables for API keys. Never hardcode them in your source code.

API Reference

Complete API documentation with examples

License Validation

Method: client.validate.validate(userId)

Validates a user's license and returns the validation result. This is the primary method for checking if a user has a valid license.

Parameters:

  • userId (string, required): The tenant's internal user ID

Returns:

type ValidateLicenseResponse = 
  | { valid: true; license: License; activation?: Activation; features?: string[] }
  | { valid: false; reason: 'expired' | 'revoked' | 'suspended' | 'exceeded_seats' | 'no_license' | 'user_not_found' };

Example:

const result = await client.validate.validate('user_123');

if (result.valid) {
  // License is valid
  console.log('License ID:', result.license.id);
  console.log('Status:', result.license.status);
  console.log('Features:', result.features || []);
  
  if (result.license.expiresAt) {
    console.log('Expires at:', result.license.expiresAt);
  }
} else {
  // License is invalid
  console.log('License invalid:', result.reason);
  // Handle invalid license (e.g., show upgrade prompt)
}

User Management

Method: client.users.createUser(params)

Creates a new user in the system. Users are identified by their externalId, which should be your internal user identifier.

Parameters:

interface CreateUserRequest {
  externalId: string;              // Required: Your internal user ID
  email?: string;                  // Optional
  name?: string;                   // Optional
  metadata?: Record<string, any>;  // Optional
}

Returns:

Promise resolving to a LaaSUser object

Example:

// Create user with minimal data
const user = await client.users.createUser({
  externalId: 'user_123'
});

// Create user with full data
const user = await client.users.createUser({
  externalId: 'user_123',
  email: 'user@example.com',
  name: 'John Doe',
  metadata: {
    source: 'signup_form',
    plan: 'premium'
  }
});

console.log('Created user:', user.id);
console.log('External ID:', user.externalId);

License Management

Method: client.licenses.assignLicense(licenseId, userId, metadata?)

Assigns a license to a user. This creates a relationship between a license and a user, allowing the user to use the license.

Parameters:

  • licenseId (string, required): The license ID to assign
  • userId (string, required): The user ID to assign the license to
  • metadata (object, optional): Additional metadata for the assignment

Returns:

Promise resolving to a UserLicense object

Example:

const assignment = await client.licenses.assignLicense(
  'license_123',
  'user_456',
  {
    source: 'admin_panel',
    assignedBy: 'admin_user_1'
  }
);

console.log('License assigned:', assignment.id);
console.log('User ID:', assignment.userId);
console.log('License ID:', assignment.licenseId);

Method: client.licenses.updateLicenseStatus(licenseId, status)

Updates a license's status. This allows you to suspend, revoke, or reactivate licenses.

Parameters:

  • licenseId (string, required): The license ID to update
  • status (LicenseStatus, required): The new status - 'active', 'suspended', 'revoked', or 'expired'

Returns:

Promise resolving to the updated License object

Example:

// Suspend a license
const license = await client.licenses.updateLicenseStatus(
  'license_123',
  'suspended'
);

// Reactivate a license
const license = await client.licenses.updateLicenseStatus(
  'license_123',
  'active'
);

console.log('License status:', license.status);

Error Handling

Handle errors gracefully in your application

The SDK provides custom error classes for different error scenarios. All errors extend fromSliceError, making it easy to handle them consistently.

Error Classes

SliceError

Base error class for all SDK errors

SliceAPIError

API errors (4xx, 5xx status codes). Includes statusCode and response properties.

SliceAuthenticationError

Authentication errors (401, 403). Invalid API key or insufficient permissions.

SliceValidationError

Validation errors (400). Invalid request parameters.

SliceNetworkError

Network connectivity errors. Failed to connect to the API.

SliceTimeoutError

Request timeout errors. Request exceeded the timeout duration.

Error Handling Example

import {
  SliceClient,
  SliceAuthenticationError,
  SliceValidationError,
  SliceNetworkError,
  SliceTimeoutError,
  SliceAPIError,
} from '@sliceapi/sdk';

const client = new SliceClient(process.env.SLICE_API_KEY!);

try {
  const result = await client.validate.validate('user_123');
  // Handle success...
} catch (error) {
  if (error instanceof SliceAuthenticationError) {
    // Invalid API key or authentication failed
    console.error('Auth error:', error.message, error.statusCode);
    // Redirect to login or show error message
  } else if (error instanceof SliceValidationError) {
    // Invalid request parameters
    console.error('Validation error:', error.message);
    // Show user-friendly error message
  } else if (error instanceof SliceNetworkError) {
    // Network connectivity issue
    console.error('Network error:', error.message);
    // Show retry option or offline message
  } else if (error instanceof SliceTimeoutError) {
    // Request timed out
    console.error('Timeout:', error.message);
    // Show retry option
  } else if (error instanceof SliceAPIError) {
    // Other API errors (4xx, 5xx)
    console.error('API error:', error.message, error.statusCode);
    // Handle based on status code
  } else {
    // Unknown error
    console.error('Unknown error:', error);
  }
}

Best Practice: Always handle errors appropriately in your application. Provide user-friendly error messages and implement retry logic for network errors when appropriate.

TypeScript Support

Full type safety with exported types

The SDK is written in TypeScript and provides full type definitions. All types are exported for your convenience, allowing you to use them in your own code.

Available Types

import type {
  // Core types
  Tenant,
  TenantApiKey,
  LaaSUser,
  Product,
  Plan,
  License,
  LicenseStatus,
  UserLicense,
  Activation,
  AuditLog,
  AuditLogAction,
  
  // Request/Response types
  ValidateLicenseRequest,
  ValidateLicenseResponse,
  CreateUserRequest,
  AssignLicenseRequest,
  ApiResponse,
  
  // SDK-specific types
  SliceClientOptions,
} from '@sliceapi/sdk';

Example: Using Types

import { SliceClient } from '@sliceapi/sdk';
import type { ValidateLicenseResponse, LicenseStatus } from '@sliceapi/sdk';

const client = new SliceClient(process.env.SLICE_API_KEY!);

async function checkLicense(userId: string): Promise<ValidateLicenseResponse> {
  return await client.validate.validate(userId);
}

async function updateLicense(
  licenseId: string, 
  status: LicenseStatus
) {
  return await client.licenses.updateLicenseStatus(licenseId, status);
}

Complete Examples

Real-world integration examples

Complete Workflow Example

This example shows a complete workflow: creating a user, assigning a license, and validating it.

import { SliceClient, SliceAuthenticationError } from '@sliceapi/sdk';

const client = new SliceClient(process.env.SLICE_API_KEY!, {
  baseUrl: process.env.SLICE_API_URL
});

async function setupUserWithLicense(
  externalId: string,
  email: string,
  licenseId: string
) {
  try {
    // Step 1: Create user
    const user = await client.users.createUser({
      externalId,
      email,
      name: 'New User',
      metadata: { source: 'signup' }
    });
    console.log('User created:', user.id);

    // Step 2: Assign license
    const assignment = await client.licenses.assignLicense(
      licenseId,
      externalId,
      { source: 'signup_flow' }
    );
    console.log('License assigned:', assignment.id);

    // Step 3: Validate license
    const validation = await client.validate.validate(externalId);
    if (validation.valid) {
      console.log('License is valid!');
      console.log('Features:', validation.features);
      return true;
    } else {
      console.log('License validation failed:', validation.reason);
      return false;
    }
  } catch (error) {
    if (error instanceof SliceAuthenticationError) {
      console.error('Authentication failed');
    } else {
      console.error('Error:', error);
    }
    throw error;
  }
}

Node.js Example

Example of using the SDK in a Node.js backend service.

// server.ts
import { SliceClient } from '@sliceapi/sdk';
import express from 'express';

const app = express();
const client = new SliceClient(process.env.SLICE_API_KEY!, {
  baseUrl: process.env.SLICE_API_URL
});

// Middleware to check license
async function checkLicense(req: express.Request, res: express.Response, next: express.NextFunction) {
  const userId = req.headers['x-user-id'] as string;
  
  if (!userId) {
    return res.status(401).json({ error: 'User ID required' });
  }

  try {
    const result = await client.validate.validate(userId);
    if (!result.valid) {
      return res.status(403).json({ 
        error: 'License invalid', 
        reason: result.reason 
      });
    }
    
    // Attach license info to request
    req.license = result.license;
    req.features = result.features || [];
    next();
  } catch (error) {
    console.error('License validation error:', error);
    return res.status(500).json({ error: 'License validation failed' });
  }
}

// Protected route
app.get('/api/premium-feature', checkLicense, (req, res) => {
  const features = req.features || [];
  if (!features.includes('premium')) {
    return res.status(403).json({ error: 'Premium feature not available' });
  }
  
  res.json({ message: 'Premium feature accessed' });
});

Browser Example

Example of using the SDK in a browser application (React).

// LicenseCheck.tsx
import { useEffect, useState } from 'react';
import { SliceClient } from '@sliceapi/sdk';

const client = new SliceClient(import.meta.env.VITE_SLICE_API_KEY, {
  baseUrl: import.meta.env.VITE_SLICE_API_URL
});

export function LicenseCheck({ userId }: { userId: string }) {
  const [isValid, setIsValid] = useState<boolean | null>(null);
  const [features, setFeatures] = useState<string[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function validateLicense() {
      try {
        const result = await client.validate.validate(userId);
        setIsValid(result.valid);
        if (result.valid) {
          setFeatures(result.features || []);
        }
      } catch (error) {
        console.error('License validation failed:', error);
        setIsValid(false);
      } finally {
        setLoading(false);
      }
    }

    validateLicense();
  }, [userId]);

  if (loading) {
    return <div>Checking license...</div>;
  }

  if (!isValid) {
    return <div>License is invalid. Please upgrade your plan.</div>;
  }

  return (
    <div>
      <h2>License Valid</h2>
      <ul>
        {features.map(feature => (
          <li key={feature}>{feature}</li>
        ))}
      </ul>
    </div>
  );
}