# Platform SDK Reference

Source: https://wraps.dev/docs/client-sdk-reference

# @wraps.dev/client SDK

A type-safe API client for the Wraps Platform. Built on openapi-fetch with full TypeScript support generated from the OpenAPI schema.

## Installation

Copy for AI

npmpnpmyarnbun

npm install @wraps.dev/client

## Quick Start

Copy for AI

example.ts

```
import { createPlatformClient } from '@wraps.dev/client';const client = createPlatformClient({  apiKey: process.env.WRAPS_API_KEY,});// List contactsconst { data, error } = await client.GET('/v1/contacts/', {  params: {    query: { page: '1', pageSize: '10' },  },});if (data) {  console.log('Contacts:', data.contacts);}
```

## Initialization

Copy for AI

Create a type-safe API client for the Wraps Platform.

Function

`createPlatformClient(config: WrapsPlatformConfig): PlatformClient`

#### Options

-   `apiKey` (required): Your Wraps API key
-   `baseUrl` (optional): API base URL. Defaults to `https://api.wraps.dev`

config.ts

```
import { createPlatformClient } from '@wraps.dev/client';const client = createPlatformClient({  apiKey: process.env.WRAPS_API_KEY,  // Optional: custom base URL (defaults to https://api.wraps.dev)  baseUrl: 'https://api.wraps.dev',});
```

## Contacts API

Copy for AI

Manage contacts in your Wraps organization.

### List Contacts

list-contacts.ts

```
// List contacts with paginationconst { data, error } = await client.GET('/v1/contacts/', {  params: {    query: {      page: '1',      pageSize: '20',      // Optional filters      search: 'john@example.com',      status: 'active',    },  },});if (error) {  console.error('Error:', error);} else {  console.log('Total contacts:', data.total);  data.contacts.forEach(contact => {    console.log(contact.email, contact.emailStatus);  });}
```

### Create Contact

create-contact.ts

```
// Create a new contactconst { data, error } = await client.POST('/v1/contacts/', {  body: {    email: 'user@example.com',    emailStatus: 'active',    firstName: 'John',    lastName: 'Doe',    metadata: {      source: 'api',      plan: 'pro',    },    topicIds: ['topic-123', 'topic-456'], // Optional topic subscriptions  },});if (data) {  console.log('Created contact:', data.id);}
```

### Get Contact

get-contact.ts

```
// Get a single contact by IDconst { data, error } = await client.GET('/v1/contacts/{id}', {  params: {    path: { id: 'contact-123' },  },});if (data) {  console.log('Contact:', data.email);  console.log('Topics:', data.topics);}
```

### Update Contact

update-contact.ts

```
// Update an existing contactconst { data, error } = await client.PATCH('/v1/contacts/{id}', {  params: {    path: { id: 'contact-123' },  },  body: {    firstName: 'Jane',    metadata: {      updated: true,    },  },});
```

### Delete Contacts

delete-contacts.ts

```
// Delete a single contactconst { error } = await client.DELETE('/v1/contacts/{id}', {  params: {    path: { id: 'contact-123' },  },});// Bulk delete contacts (max 100)const { error: bulkError } = await client.DELETE('/v1/contacts/', {  body: {    ids: ['contact-123', 'contact-456', 'contact-789'],  },});
```

## Batch Sends API

Copy for AI

Create and manage batch email sends.

### Create Batch Send

create-batch.ts

```
// Create a batch send jobconst { data, error } = await client.POST('/v1/batch/', {  body: {    templateId: 'template-abc',    segmentId: 'segment-xyz', // or use contactIds    // Optional: schedule for later    scheduledAt: '2025-01-15T10:00:00Z',  },});if (data) {  console.log('Batch ID:', data.id);  console.log('Status:', data.status);}
```

### Get Batch Status

get-batch.ts

```
// Get batch send statusconst { data, error } = await client.GET('/v1/batch/{id}', {  params: {    path: { id: 'batch-123' },  },});if (data) {  console.log('Status:', data.status); // queued, processing, completed, failed  console.log('Total:', data.total);  console.log('Sent:', data.sent);  console.log('Failed:', data.failed);}
```

### Cancel Batch

cancel-batch.ts

```
// Cancel a scheduled or queued batchconst { error } = await client.DELETE('/v1/batch/{id}', {  params: {    path: { id: 'batch-123' },  },});if (!error) {  console.log('Batch cancelled successfully');}
```

## Events API

Copy for AI

Track custom events for contacts to trigger workflows, record activity, and resume waiting automation steps. See the [Custom Events guide](https://wraps.dev/docs/guides/custom-events) for full details.

### Track Event

track-event.ts

```
// Track a single eventconst result = await client.track('purchase.completed', {  contactEmail: 'alice@example.com',  properties: {    orderId: 'ord_12345',    amount: 99.00,    plan: 'pro',  },});// { success: true, contactCreated: false, workflowsTriggered: 1, executionsResumed: 0 }
```

### Auto-Create Contacts

Set `createIfMissing: true` to create a new contact when one doesn't exist.

track-create-contact.ts

```
// Auto-create contact if they don't existawait client.track('signup.completed', {  contactEmail: 'new-user@example.com',  contactName: 'Alice',  createIfMissing: true,  properties: {    source: 'website',    referrer: 'producthunt',  },});
```

### Batch Events

track-batch.ts

```
// Send multiple events in one requestconst result = await client.trackBatch([  {    name: 'page.viewed',    contactEmail: 'alice@example.com',    properties: { page: '/pricing' },  },  {    name: 'feature.used',    contactId: 'con_abc123',    properties: { feature: 'api-keys' },  },]);// { success: true, processed: 2, workflowsTriggered: 0, executionsResumed: 0, errors: [] }
```

### TrackOptions

| Option | Type | Description |
| --- | --- | --- |
| contactId | string | Contact ID (provide this or `contactEmail`) |
| contactEmail | string | Contact email (alternative to `contactId`) |
| contactName | string | Sets `firstName` when `createIfMissing` creates a new contact |
| createIfMissing | boolean | Create the contact if they don't exist (default: `false`) |
| properties | object | Arbitrary key-value data attached to the event |

## Error Handling

Copy for AI

The SDK uses openapi-fetch which returns errors as part of the response object rather than throwing.

error-handling.ts

```
import { createPlatformClient } from '@wraps.dev/client';const client = createPlatformClient({  apiKey: process.env.WRAPS_API_KEY,});const { data, error, response } = await client.GET('/v1/contacts/');if (error) {  // error is typed based on the API response  console.error('API Error:', error);  console.error('Status:', response?.status);} else {  // data is fully typed  console.log('Success:', data);}
```

## TypeScript Support

Copy for AI

The SDK is fully typed using OpenAPI schema generation. All endpoints, request bodies, and responses are type-safe.

typed-usage.ts

```
import { createPlatformClient, type paths } from '@wraps.dev/client';const client = createPlatformClient({  apiKey: process.env.WRAPS_API_KEY,});// Full type safety - TypeScript knows the response shapeconst { data } = await client.GET('/v1/contacts/');// data is typed as the API responseif (data) {  // TypeScript knows data.contacts is an array  data.contacts.forEach(contact => {    console.log(contact.email); // TS knows this exists  });}
```

## defineConfig()

Copy for AI

Configure your Wraps project with environment-specific settings, template directories, and preview options.

wraps.config.ts

```
import { defineConfig } from '@wraps.dev/client';export default defineConfig({  org: 'your-org-slug',           // Organization slug (from dashboard)  from: 'hello@yourdomain.com',   // Default sender address  replyTo: 'support@yourdomain.com', // Default reply-to  region: 'us-east-1',            // AWS region  environments: {                  // Environment overrides    staging: { from: 'staging@yourdomain.com' },    production: { from: 'hello@yourdomain.com' },  },  defaultEnv: 'production',       // Default environment  templatesDir: './templates',     // Template source directory  workflowsDir: './workflows',    // Workflow source directory  brandFile: './brand.ts',        // Brand kit file  preview: {                       // Preview server config    port: 3333,  },});
```

#### Options

| Option | Type | Description |
| --- | --- | --- |
| `org` | string | Organization slug from your dashboard |
| `from` | string | Default sender email address |
| `replyTo` | string | Default reply-to address (optional) |
| `region` | string | AWS region (optional) |
| `environments` | object | Per-environment overrides (optional) |
| `defaultEnv` | string | Default environment name (optional) |
| `templatesDir` | string | Path to template source files (optional) |
| `workflowsDir` | string | Path to workflow source files (optional) |
| `brandFile` | string | Path to brand kit file (optional) |
| `preview` | object | Preview server configuration (optional) |

## defineBrand()

Copy for AI

Define your brand kit for consistent email styling across all templates.

brand.ts

```
import { defineBrand } from '@wraps.dev/client';export default defineBrand({  companyName: 'Your Company',  colors: {    primary: '#6366f1',    secondary: '#a5b4fc',    background: '#ffffff',    text: '#1f2937',    muted: '#9ca3af',  },  fonts: {    heading: 'Inter, sans-serif',    body: 'Inter, sans-serif',  },  buttonStyle: {    borderRadius: '6px',    padding: '12px 24px',  },  logoUrl: 'https://yourdomain.com/logo.png',  address: '123 Main St, San Francisco, CA 94102',  socialLinks: {    twitter: 'https://twitter.com/yourcompany',    github: 'https://github.com/yourcompany',  },});
```

#### Options

| Option | Type | Description |
| --- | --- | --- |
| `companyName` | string | Your company name |
| `colors` | object | Brand colors (primary, secondary, background, text, muted) |
| `fonts` | object | Font families for heading and body text |
| `buttonStyle` | object | Default button styling (borderRadius, padding) |
| `logoUrl` | string | URL to your company logo |
| `address` | string | Physical address (for email footers) |
| `socialLinks` | object | Social media URLs (optional) |

## defineWorkflow()

Copy for AI

Define automated email workflows with triggers, conditions, and multi-step sequences. See the full [Building Workflows guide](https://wraps.dev/docs/guides/workflows) for details.

welcome-workflow.ts

```
import { defineWorkflow, sendEmail, delay, exit } from '@wraps.dev/client';export default defineWorkflow({  name: 'Welcome Sequence',  trigger: { type: 'contact.created' },  settings: { maxEnrollments: 1 },  steps: [    sendEmail('welcome', { template: 'welcome-email' }),    delay('wait', { days: 1 }),    sendEmail('followup', { template: 'day-2-followup' }),    exit('done'),  ],});
```

#### Workflow Step Helpers

| Helper | Signature |
| --- | --- |
| `sendEmail` | `sendEmail(id, { template, from?, fromName? })` |
| `sendSms` | `sendSms(id, { template?, message? })` |
| `delay` | `delay(id, { days?, hours?, minutes? })` |
| `condition` | `condition(id, { field, operator, value, branches: { yes: [], no: [] } })` |
| `waitForEvent` | `waitForEvent(id, { eventName, timeout? })` |
| `waitForEmailEngagement` | `waitForEmailEngagement(id, { emailStepId, engagementType, timeout? })` |
| `exit` | `exit(id, { reason?, markAs? })` |
| `updateContact` | `updateContact(id, { updates: [{ field, operation, value }] })` |
| `subscribeTopic` | `subscribeTopic(id, { topicId, channel })` |
| `unsubscribeTopic` | `unsubscribeTopic(id, { topicId, channel })` |
| `webhook` | `webhook(id, { url, method?, headers?, body? })` |

## Next Steps

View on npm

Check out the package on npm for the latest version and changelog.

[View Package](https://www.npmjs.com/package/@wraps.dev/client)

View on GitHub

Explore the source code, report issues, or contribute.

[View Source](https://github.com/wraps-team/wraps-js)

Email SDK

Send emails directly through AWS SES with the Email SDK.

[View Docs](https://wraps.dev/docs/sdk-reference)
