Getting Started

Step-by-step guide to your first PromptCompose SDK integration

SDK Getting Started Guide

This comprehensive guide will walk you through everything you need to know to start using the PromptCompose SDK effectively in your applications.

Prerequisites

Before starting, ensure you have:

Step 1: Basic Setup

Get Your Credentials

From your PromptCompose platform:

  1. Log in to your PromptCompose Console
  2. Navigate to Integrations in your project
  3. Copy your API Key (starts with pc_)
  4. Copy your Project ID (starts with proj_)

Initialize the SDK

Create your first PromptCompose instance:

import { PromptCompose } from '@promptcompose/sdk';

const promptCompose = new PromptCompose(
  'pc_your_api_key_here',      // Your API key
  'proj_your_project_id_here', // Your project ID
  { debug: true }              // Enable debug logging for development
);

Test the Connection

Verify your setup works:

async function testConnection() {
  try {
    const result = await promptCompose.init();
    console.log('✅ Connected successfully:', result.message);
    return true;
  } catch (error) {
    console.error('❌ Connection failed:', error.message);
    return false;
  }
}

// Test the connection
const isConnected = await testConnection();
if (!isConnected) {
  process.exit(1);
}

Step 2: Your First Prompt Resolution

List Available Prompts

First, let’s see what prompts are available in your project:

async function listPrompts() {
  try {
    const prompts = await promptCompose.listPrompts();
    console.log(`Found ${prompts.length} prompts:`);
    
    prompts.forEach(prompt => {
      console.log(`- ${prompt.name} (ID: ${prompt.publicId})`);
      console.log(`  Versions: ${prompt.versions.length}`);
      console.log(`  Variables: ${prompt.versions[0]?.variables.map(v => v.name).join(', ') || 'None'}`);
    });
    
    return prompts;
  } catch (error) {
    console.error('Failed to list prompts:', error.message);
  }
}

const prompts = await listPrompts();

Resolve a Simple Prompt

Let’s resolve a prompt without any variables:

async function resolveSimplePrompt(promptId: string) {
  try {
    const result = await promptCompose.resolvePrompt(promptId);
    console.log('Resolved prompt:', result.content);
    console.log('Source:', result.source); // "version" if no A/B test
    return result;
  } catch (error) {
    console.error('Failed to resolve prompt:', error.message);
  }
}

// Use a prompt ID from your project
const result = await resolveSimplePrompt('your-prompt-id-here');

Resolve a Prompt with Variables

If your prompt contains variables (like {{userName}}), provide them:

async function resolvePromptWithVariables(promptId: string) {
  try {
    const result = await promptCompose.resolvePrompt(
      promptId,
      undefined, // No specific configuration
      {
        userName: 'Alice',
        companyName: 'Acme Corp',
        productName: 'Widget Pro'
      }
    );
    
    console.log('Resolved prompt with variables:', result.content);
    return result;
  } catch (error) {
    console.error('Failed to resolve prompt:', error.message);
  }
}

const result = await resolvePromptWithVariables('prompt-with-variables-id');

Step 3: Understanding Prompt Structure

Examine a Prompt

Let’s look at the structure of a specific prompt:

async function examinePrompt(promptId: string) {
  try {
    const prompt = await promptCompose.getPrompt(promptId);
    
    console.log('Prompt Details:');
    console.log('- Name:', prompt.name);
    console.log('- ID:', prompt.publicId);
    console.log('- Created:', prompt.createdAt);
    console.log('- Versions:', prompt.versions.length);
    
    // Examine the latest version
    const latestVersion = prompt.versions[0];
    console.log('\nLatest Version:');
    console.log('- Title:', latestVersion.title);
    console.log('- Content:', latestVersion.content);
    console.log('- Variables:', latestVersion.variables.length);
    
    // List variables
    if (latestVersion.variables.length > 0) {
      console.log('\nVariables:');
      latestVersion.variables.forEach(variable => {
        console.log(`- ${variable.name} (${variable.type})${variable.required ? ' *required*' : ''}`);
        console.log(`  Label: ${variable.label}`);
        console.log(`  Description: ${variable.description}`);
        if (variable.defaultValue) {
          console.log(`  Default: ${variable.defaultValue}`);
        }
      });
    }
    
    return prompt;
  } catch (error) {
    console.error('Failed to examine prompt:', error.message);
  }
}

const promptDetails = await examinePrompt('your-prompt-id');

Step 4: Working with Versions

Use a Specific Version

To use a specific version instead of the latest:

async function useSpecificVersion(promptId: string, versionId: string) {
  const config = {
    config: {
      versionId: versionId,
      abTesting: { enabled: false } // Disable A/B testing
    }
  };
  
  const result = await promptCompose.resolvePrompt(promptId, config);
  console.log(`Using version ${versionId}:`, result.content);
  return result;
}

// Use version 'v1' of your prompt
await useSpecificVersion('your-prompt-id', 'v1');

Compare Versions

See the difference between versions:

async function compareVersions(promptId: string) {
  const prompt = await promptCompose.getPrompt(promptId);
  
  if (prompt.versions.length < 2) {
    console.log('Not enough versions to compare');
    return;
  }
  
  const latest = prompt.versions[0];
  const previous = prompt.versions[1];
  
  console.log('Version Comparison:');
  console.log(`Latest (${latest.title}):`);
  console.log(latest.content);
  console.log(`\nPrevious (${previous.title}):`);
  console.log(previous.content);
  
  // Check for variable differences
  const latestVarNames = latest.variables.map(v => v.name);
  const previousVarNames = previous.variables.map(v => v.name);
  
  const addedVars = latestVarNames.filter(name => !previousVarNames.includes(name));
  const removedVars = previousVarNames.filter(name => !latestVarNames.includes(name));
  
  if (addedVars.length > 0) {
    console.log('\nAdded Variables:', addedVars);
  }
  if (removedVars.length > 0) {
    console.log('Removed Variables:', removedVars);
  }
}

Step 5: Introduction to A/B Testing

Check for A/B Tests

See if your project has any A/B tests:

async function checkABTests() {
  try {
    const tests = await promptCompose.listABTests();
    console.log(`Found ${tests.length} A/B tests:`);
    
    tests.forEach(test => {
      console.log(`- ${test.name} (${test.status})`);
      console.log(`  Strategy: ${test.rolloutStrategy}`);
      console.log(`  Variants: ${test.variants.length}`);
      console.log(`  Prompt: ${test.prompt.name}`);
    });
    
    return tests;
  } catch (error) {
    console.error('Failed to list A/B tests:', error.message);
  }
}

const abTests = await checkABTests();

Resolve with A/B Testing

If your prompt has an active A/B test, it will automatically be used:

async function resolveWithABTest(promptId: string, sessionId: string) {
  const config = {
    config: {
      abTesting: {
        sessionId: sessionId // Ensures consistent variant for this session
      }
    }
  };
  
  const result = await promptCompose.resolvePrompt(promptId, config);
  
  console.log('Resolved content:', result.content);
  console.log('Source:', result.source); // "variant" if A/B test active
  
  if (result.variant) {
    console.log('A/B Test variant used:', result.variant.name);
    console.log('A/B Test name:', result.abTest?.name);
    
    // Store these IDs for later conversion reporting
    return {
      content: result.content,
      variantId: result.variant.publicId,
      testId: result.abTest?.publicId,
      sessionId: sessionId
    };
  }
  
  return { content: result.content };
}

// Use a session ID that identifies your user/session
const abResult = await resolveWithABTest('prompt-with-ab-test', 'user-123-session');

Report A/B Test Results

When users perform the desired action, report the outcome:

async function reportConversion(testId: string, variantId: string, sessionId: string, success: boolean) {
  try {
    await promptCompose.reportABResult(testId, {
      variantId: variantId,
      status: success ? 'success' : 'fail',
      sessionId: sessionId
    });
    
    console.log(`Reported ${success ? 'success' : 'failure'} for variant ${variantId}`);
  } catch (error) {
    console.error('Failed to report conversion:', error.message);
  }
}

// If the A/B test result led to a successful outcome
if (abResult.testId && abResult.variantId) {
  await reportConversion(abResult.testId, abResult.variantId, abResult.sessionId, true);
}

Step 6: Complete Working Example

Here’s a complete example that demonstrates the main features:

import { PromptCompose, ValidationError, APIError } from '@promptcompose/sdk';
import dotenv from 'dotenv';

// Load environment variables
dotenv.config();

class PromptService {
  private sdk: PromptCompose;
  
  constructor(apiKey: string, projectId: string) {
    this.sdk = new PromptCompose(apiKey, projectId, { 
      debug: process.env.NODE_ENV === 'development' 
    });
  }
  
  async initialize(): Promise<boolean> {
    try {
      await this.sdk.init();
      console.log('PromptCompose SDK initialized successfully');
      return true;
    } catch (error) {
      console.error('Failed to initialize SDK:', error.message);
      return false;
    }
  }
  
  async getWelcomeMessage(userId: string, userName: string, companyName: string): Promise<string> {
    try {
      const result = await this.sdk.resolvePrompt(
        'welcome-message-prompt', // Replace with your prompt ID
        {
          config: {
            abTesting: {
              sessionId: `user-${userId}` // Consistent variant per user
            }
          }
        },
        {
          userName: userName,
          companyName: companyName,
          currentDate: new Date().toLocaleDateString()
        }
      );
      
      // Track if this was an A/B test
      if (result.variant && result.abTest) {
        console.log(`Served variant "${result.variant.name}" from test "${result.abTest.name}"`);
        
        // Store for later conversion tracking
        this.trackPromptServed(result.abTest.publicId, result.variant.publicId, userId);
      }
      
      return result.content;
    } catch (error) {
      if (error instanceof ValidationError) {
        console.error('Invalid input:', error.message);
        return 'Welcome! Please check your account settings.';
      } else if (error instanceof APIError) {
        console.error('API Error:', error.message);
        return 'Welcome! We\'re experiencing some technical difficulties.';
      } else {
        console.error('Unexpected error:', error.message);
        return 'Welcome!';
      }
    }
  }
  
  async reportUserAction(testId: string, variantId: string, userId: string, success: boolean): Promise<void> {
    try {
      await this.sdk.reportABResult(testId, {
        variantId: variantId,
        status: success ? 'success' : 'fail',
        sessionId: `user-${userId}`
      });
      console.log('User action reported successfully');
    } catch (error) {
      console.error('Failed to report user action:', error.message);
    }
  }
  
  private trackPromptServed(testId: string, variantId: string, userId: string): void {
    // Your analytics tracking logic here
    console.log(`Analytics: Test ${testId}, Variant ${variantId}, User ${userId}`);
  }
}

// Usage
async function main() {
  const promptService = new PromptService(
    process.env.PROMPT_COMPOSE_API_KEY!,
    process.env.PROMPT_COMPOSE_PROJECT_ID!
  );
  
  const initialized = await promptService.initialize();
  if (!initialized) {
    console.error('Could not initialize prompt service');
    return;
  }
  
  // Get a welcome message for a user
  const welcomeMessage = await promptService.getWelcomeMessage(
    '123',
    'Alice Johnson',
    'Acme Corporation'
  );
  
  console.log('Welcome message:', welcomeMessage);
  
  // Later, if the user performs the desired action:
  // await promptService.reportUserAction('test-id', 'variant-id', '123', true);
}

main().catch(console.error);

Step 7: Environment Setup for Production

Create Environment Configuration

Set up different configurations for different environments:

// config/environments.ts
export const environments = {
  development: {
    apiKey: process.env.DEV_PROMPT_COMPOSE_API_KEY!,
    projectId: process.env.DEV_PROMPT_COMPOSE_PROJECT_ID!,
    debug: true,
    apiUrl: 'http://localhost:8080/api/v1'
  },
  staging: {
    apiKey: process.env.STAGING_PROMPT_COMPOSE_API_KEY!,
    projectId: process.env.STAGING_PROMPT_COMPOSE_PROJECT_ID!,
    debug: true,
    apiUrl: 'https://staging-api.promptcompose.io/api/v1'
  },
  production: {
    apiKey: process.env.PROMPT_COMPOSE_API_KEY!,
    projectId: process.env.PROMPT_COMPOSE_PROJECT_ID!,
    debug: false,
    apiUrl: 'https://api.promptcompose.io/api/v1'
  }
};

export function getConfig() {
  const env = process.env.NODE_ENV || 'development';
  return environments[env] || environments.development;
}

Use Environment Configuration

import { PromptCompose } from '@promptcompose/sdk';
import { getConfig } from './config/environments';

const config = getConfig();
const promptCompose = new PromptCompose(
  config.apiKey,
  config.projectId,
  { debug: config.debug }
);

// Set custom API URL if needed
if (config.apiUrl) {
  process.env.PROMPT_COMPOSE_API_URL = config.apiUrl;
}

Next Steps

Now that you have the basics working, explore these advanced topics:

Advanced Features

Integration Examples

Production Readiness

Common Patterns

Simple Prompt Service

For basic prompt resolution:

class SimplePromptService {
  private sdk: PromptCompose;

  constructor(apiKey: string, projectId: string) {
    this.sdk = new PromptCompose(apiKey, projectId);
  }

  async resolve(promptId: string, variables: Record<string, any> = {}): Promise<string> {
    const result = await this.sdk.resolvePrompt(promptId, undefined, variables);
    return result.content;
  }
}

A/B Testing Service

For advanced A/B testing:

class ABTestingService {
  private sdk: PromptCompose;
  private sessions = new Map<string, any>();

  constructor(apiKey: string, projectId: string) {
    this.sdk = new PromptCompose(apiKey, projectId);
  }

  async serveWithTesting(promptId: string, userId: string, variables: any) {
    const result = await this.sdk.resolvePrompt(promptId, {
      config: { abTesting: { sessionId: userId } }
    }, variables);

    if (result.variant && result.abTest) {
      this.sessions.set(userId, {
        testId: result.abTest.publicId,
        variantId: result.variant.publicId
      });
    }

    return result.content;
  }

  async reportConversion(userId: string, success: boolean) {
    const session = this.sessions.get(userId);
    if (session) {
      await this.sdk.reportABResult(session.testId, {
        variantId: session.variantId,
        status: success ? 'success' : 'fail',
        sessionId: userId
      });
    }
  }
}

Troubleshooting

Common Issues

Authentication Errors

Error: Failed to initialize SDK
  • Verify your API key and project ID are correct
  • Check that your API key has proper permissions
  • Ensure environment variables are loaded

Variable Validation Errors

Error: Missing required variable(s): userName
  • Check what variables your prompt expects
  • Provide all required variables when resolving
  • Use the examinePrompt function to see variable requirements

Network Issues

Error: Network Error
  • Check your internet connection
  • Verify the API URL is accessible
  • Check if you’re behind a firewall or proxy

Prompt Not Found

Error: Failed to fetch prompt xyz
  • Verify the prompt ID exists in your project
  • Check that the prompt is published/active
  • Ensure you’re using the correct project

Getting Help

For additional support:

  1. Check the API Reference for detailed method documentation
  2. Review Best Practices for production guidance
  3. See Troubleshooting Guide for common issues
  4. Contact support if problems persist

Summary

You’ve learned how to:

  • ✅ Install and configure the PromptCompose SDK
  • ✅ Initialize and test the connection
  • ✅ List and examine prompts in your project
  • ✅ Resolve prompts with and without variables
  • ✅ Work with specific versions
  • ✅ Use A/B testing features
  • ✅ Handle errors gracefully
  • ✅ Set up environment-specific configurations

You’re now ready to integrate PromptCompose into your application! Continue with the specialized guides to learn about advanced features and production best practices.