npm package: @potion5/sdk
Description: Official TypeScript SDK for the Potion API - AI-powered beverage formulation platform
Author: Potion
Latest version: 1.0.0

# Potion TypeScript/Node.js SDK

Official TypeScript SDK for the Potion API - AI-powered beverage formulation platform.

## Installation

```bash
npm install @potion/sdk
# or
yarn add @potion/sdk
# or
pnpm add @potion/sdk
```

## Quick Start

```typescript
import { Potion } from '@potion/sdk';

// Initialize the client
const client = new Potion({ apiKey: 'pk_live_your_key_here' });

// Generate a formulation
const formulation = await client.formulations.generate({
  prompt: 'A refreshing citrus energy drink with natural caffeine',
  category: 'nonalc',
  subcategory: 'csd.energy_drink',
  constraints: ['natural', 'under-100-calories'],
});

console.log(`Created: ${formulation.name}`);
console.log(`Calories: ${formulation.nutrition.calories}`);
```

## Features

- **Full TypeScript support** - Complete type definitions
- **Promise-based** - Async/await ready
- **Automatic retries** - Built-in retry logic with exponential backoff
- **Streaming** - Support for SSE streaming responses
- **Rate limiting** - Automatic rate limit handling
- **Tree-shakeable** - Import only what you need

## Usage

### Formulations

```typescript
import { Potion } from '@potion/sdk';

const client = new Potion({ apiKey: 'pk_live_your_key_here' });

// List formulations
const { data: formulations } = await client.formulations.list({
  limit: 20,
  status: 'active',
});

// Get a specific formulation
const formulation = await client.formulations.get('formulation-uuid');

// Generate with AI
const generated = await client.formulations.generate({
  prompt: 'Low-sugar probiotic kombucha',
  category: 'nonalc',
  subcategory: 'functional.kombucha',
});

// Create variations
const variations = await client.formulations.createVariations(
  'formulation-uuid',
  {
    variationType: 'flavor',
    count: 3,
  }
);

// Get substitutions
const substitutions = await client.formulations.getSubstitutions(
  'formulation-uuid',
  {
    ingredientName: 'Organic Cane Sugar',
    reason: 'cost',
  }
);
```

### Ingredients

```typescript
// List ingredients
const { data: ingredients } = await client.ingredients.list({
  category: 'sweetener',
});

// Search ingredients
const results = await client.ingredients.search('natural caffeine');

// Augment ingredient with AI
const augmented = await client.ingredients.augment({
  ingredientName: 'Guarana Extract',
  physicalState: 'solid',
});

// Batch augment
const batchResults = await client.ingredients.augmentBatch({
  ingredients: ['Stevia', 'Monk Fruit Extract', 'Erythritol'],
});

// Check compatibility
const compatibility = await client.ingredients.checkCompatibility(
  'Citric Acid',
  {
    withIngredients: ['Sodium Benzoate', 'Potassium Sorbate'],
  }
);
```

### SOP Generation

```typescript
// Generate SOP for a formulation
const sop = await client.sop.generate('formulation-uuid', {
  productionScale: 'commercial',
  includeHaccp: true,
});

// Get SOP profiles
const profiles = await client.sop.listProfiles();

// Retrieve existing SOP
const existing = await client.sop.get('sop-uuid');
```

### Labeling

```typescript
// Generate labeling requirements
const labeling = await client.labeling.generate('formulation-uuid', {
  containerSizeMl: 355,
  servingSizeMl: 355,
  targetMarkets: ['US', 'CA'],
});

// Check claims eligibility
const claims = await client.labeling.checkClaims({
  formulationId: 'formulation-uuid',
  claims: ['organic', 'non_gmo', 'low_calorie', 'natural'],
});
```

### Assistant

```typescript
// Chat with the assistant
const response = await client.assistant.chat({
  message: "What's the best natural sweetener for an energy drink?",
  formulationId: 'formulation-uuid', // Optional context
});

// Streaming response
const stream = await client.assistant.chatStream({
  message: 'Explain the FDA requirements for caffeine labeling',
});

for await (const chunk of stream) {
  process.stdout.write(chunk.content);
}

// List conversations
const conversations = await client.assistant.listConversations();

// Get conversation history
const conversation = await client.assistant.getConversation('conversation-uuid');
```

### Supply Chain

```typescript
// Search copackers
const copackers = await client.supplyChain.searchCopackers({
  capabilities: ['hot_fill', 'aseptic'],
  state: 'CA',
  certifications: ['SQF', 'Organic'],
});

// Get AI recommendations
const recommendations = await client.supplyChain.recommendCopackers({
  formulationId: 'formulation-uuid',
  requirements: {
    minVolume: 10000,
    certifications: ['Organic'],
  },
});

// Search distributors
const distributors = await client.supplyChain.searchDistributors({
  region: 'West Coast',
  channels: ['natural_grocery', 'specialty'],
});
```

### Compliance

```typescript
// Run compliance check
const compliance = await client.compliance.check({
  formulationId: 'formulation-uuid',
  targetStates: ['CA', 'NY', 'TX'],
});

// Get DTC shipping rules
const dtcRules = await client.compliance.getDtcShipping({
  states: ['CA', 'NY'],
  productType: 'non_alcoholic_beverage',
});

// Get regulatory updates
const updates = await client.compliance.getUpdates({
  category: 'fda',
  since: '2024-01-01',
});
```

### Webhooks

```typescript
// Create webhook
const webhook = await client.webhooks.create({
  url: 'https://your-server.com/webhook',
  events: ['formulation.created', 'formulation.updated'],
  secret: 'your-webhook-secret',
});

// List webhooks
const webhooks = await client.webhooks.list();

// Test webhook
const result = await client.webhooks.test('webhook-uuid', {
  eventType: 'formulation.created',
});

// Get delivery history
const deliveries = await client.webhooks.getDeliveries('webhook-uuid');
```

## Idempotency

Prevent duplicate operations on retries using idempotency keys:

```typescript
import { Potion, generateIdempotencyKey } from '@potion/sdk';

const client = new Potion({ apiKey: 'pk_live_your_key_here' });

// Generate a unique idempotency key
const idempotencyKey = generateIdempotencyKey();

// Use the key for mutation operations
const formulation = await client.formulations.generate(
  {
    prompt: 'A refreshing citrus energy drink',
    category: 'nonalc',
    subcategory: 'csd.energy_drink',
  },
  { idempotencyKey }
);

// If you retry with the same key, you'll get the cached response
// This prevents duplicate formulations from being created
```

Idempotency keys:
- Must be 10-255 characters (alphanumeric, hyphens, underscores)
- Are retained for 24 hours
- Only apply to mutation operations (POST, PUT, PATCH, DELETE)

## Error Handling

```typescript
import { Potion, PotionError, RateLimitError, NotFoundError } from '@potion/sdk';

const client = new Potion({ apiKey: 'pk_live_your_key_here' });

try {
  const formulation = await client.formulations.get('invalid-uuid');
} catch (error) {
  if (error instanceof NotFoundError) {
    console.log(`Formulation not found: ${error.message}`);
  } else if (error instanceof RateLimitError) {
    console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
  } else if (error instanceof PotionError) {
    console.log(`API error: ${error.code} - ${error.message}`);
  } else {
    throw error;
  }
}
```

## Configuration

```typescript
import { Potion } from '@potion/sdk';

const client = new Potion({
  apiKey: 'pk_live_your_key_here',

  // Optional configuration
  baseUrl: 'https://api.potion.com', // Custom base URL
  timeout: 30000,                     // Request timeout in milliseconds
  maxRetries: 3,                      // Max retry attempts
});
```

## Sandbox Mode

Use sandbox keys for development and testing:

```typescript
import { Potion } from '@potion/sdk';

// Use sandbox key
const client = new Potion({ apiKey: 'pk_sandbox_your_key_here' });

// Check if in sandbox mode
console.log(client.isSandbox); // true

// Check sandbox status
const status = await client.sandbox.getStatus();
console.log(`Requests remaining: ${status.usage.requestsLimit - status.usage.requestsToday}`);

// Reset sandbox data
await client.sandbox.reset();

// Load test scenario
await client.sandbox.loadScenario('energy-drink-launch');
```

## TypeScript Types

All types are exported for your convenience:

```typescript
import type {
  Formulation,
  Ingredient,
  SOPDocument,
  LabelingRequirements,
  Copacker,
  Distributor,
  Webhook,
  Conversation,
  ComplianceCheck,
  NutritionInfo,
} from '@potion/sdk';
```

## Requirements

- Node.js 18+ (or compatible runtime)
- TypeScript 4.7+ (for TypeScript users)

## License

MIT License - see LICENSE file for details.

## Support

- Documentation: https://potion.com/documentation
- API Reference: https://potion.com/api/v1/docs
- Email: api-support@potion.com