npm package: @langslide/sdk
Description: Official TypeScript SDK for Langslide API. Build powerful workflow automations and integrations with type-safe, developer-friendly APIs.
Author: Langslide
Latest version: 0.1.1

# Langslide SDK

Official TypeScript SDK for the Langslide API. Build powerful workflow automations and integrations with type-safe, developer-friendly APIs.

[![npm version](https://img.shields.io/npm/v/@langslide/sdk.svg)](https://www.npmjs.com/package/@langslide/sdk)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features

- ✅ **Complete API Coverage** - Workflows, Integrations, Users, MCP, Recipes
- ✅ **Workflow Triggering** - Execute workflows programmatically
- ✅ **Permission-Based Access Control** - Granular permissions for API keys
- ✅ **React Hooks** - Ready-to-use React hooks and context provider
- ✅ **Browser Bundle** - UMD bundle for direct browser usage
- ✅ **Enhanced Search** - Advanced filtering and sorting
- ✅ **TypeScript** - Full type definitions included
- ✅ **Error Handling** - Comprehensive error classes
- ✅ **Retry Logic** - Automatic retries with configurable timeouts

## Installation

### NPM

```bash
npm install @langslide/sdk
```

### Yarn

```bash
yarn add @langslide/sdk
```

### PNPM

```bash
pnpm add @langslide/sdk
```

### Browser (CDN)

```html
<script src="https://cdn.jsdelivr.net/npm/@langslide/sdk@latest/dist/browser.js"></script>
<script>
  const sdk = new LangslideSDK({
    apiKey: 'your-api-key'
  });
</script>
```

## Quick Start

### Node.js / TypeScript

```typescript
import { LangslideSDK } from '@langslide/sdk';

// Initialize the SDK
const sdk = new LangslideSDK({
  baseUrl: 'https://backend-api-306481332586.asia-southeast1.run.app',
  apiKey: 'your-api-key' // Optional - for JWT auth, leave empty
});

// Validate API key and fetch permissions
await sdk.setApiKey('your-api-key');

// List workflows
const workflows = await sdk.workflows.list();

// Trigger a workflow
await sdk.workflows.trigger('workflow-id', { body: { data: 'test' } });

// Get an integration
const integration = await sdk.integrations.get('slack');
```

### React

```tsx
import { LangslideProvider, useWorkflows } from '@langslide/sdk/react';

function App() {
  return (
    <LangslideProvider
      config={{
        apiKey: process.env.REACT_APP_LANGSLIDE_API_KEY
      }}
    >
      <WorkflowList />
    </LangslideProvider>
  );
}

function WorkflowList() {
  const { workflows, loading, error, triggerWorkflow } = useWorkflows();

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      {workflows.map(workflow => (
        <div key={workflow.id}>
          <h3>{workflow.name}</h3>
          <button onClick={() => triggerWorkflow(workflow.id)}>
            Trigger Workflow
          </button>
        </div>
      ))}
    </div>
  );
}
```

### Browser (Vanilla JavaScript)

```html
<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/@langslide/sdk@latest/dist/browser.js"></script>
</head>
<body>
  <div id="workflows"></div>
  <script>
    const sdk = new LangslideSDK({
      apiKey: 'your-api-key'
    });

    async function loadWorkflows() {
      await sdk.setApiKey('your-api-key');
      const workflows = await sdk.workflows.list();
      document.getElementById('workflows').innerHTML = 
        workflows.items.map(w => `<div>${w.name}</div>`).join('');
    }

    loadWorkflows();
  </script>
</body>
</html>
```

## Configuration

### Constructor Options

```typescript
const sdk = new LangslideSDK({
  baseUrl?: string;        // API base URL (default: https://backend-api-306481332586.asia-southeast1.run.app)
  apiKey?: string;         // API key for authentication (optional - for JWT, leave empty)
  timeout?: number;        // Request timeout in ms (default: 30000)
  retries?: number;        // Number of retries (default: 3)
  enableLogging?: boolean; // Enable request/response logging (default: false)
});
```

### Environment Variables

You can configure the SDK using environment variables:

- `LANGSLIDE_API_URL` - Backend API URL
- `LANGSLIDE_API_KEY` - API key for authentication

```typescript
// Uses environment variables automatically
const sdk = new LangslideSDK();

// Validate API key if provided
if (process.env.LANGSLIDE_API_KEY) {
  await sdk.setApiKey(process.env.LANGSLIDE_API_KEY);
}
```

## API Modules

### Workflows

Complete workflow management with CRUD operations and triggering.

```typescript
// List workflows with enhanced search
const workflows = await sdk.workflows.list({
  page: 1,
  limit: 10,
  status: 'active',
  search: 'email automation',
  sortBy: 'created_at',
  sortOrder: 'desc',
  createdAfter: '2024-01-01',
  tags: ['email', 'automation']
});

// Get a workflow
const workflow = await sdk.workflows.get('workflow-id');

// Create a workflow
const newWorkflow = await sdk.workflows.create({
  name: 'My Workflow',
  status: 'active'
});

// Update a workflow
await sdk.workflows.update('workflow-id', {
  status: 'inactive',
  name: 'Updated Name'
});

// Delete a workflow
await sdk.workflows.delete('workflow-id');

// Trigger a workflow (async, fire-and-forget)
const triggerResponse = await sdk.workflows.trigger('workflow-id', {
  body: { data: 'payload' },
  params: { param1: 'value1' },
  queryParams: { query: 'value' }
});
// Returns: { status: string, message: string, data: Record<string, any> }

// Get usage statistics
const usage = await sdk.workflows.getUsage();
```

**Required Permissions**: `workflows:read` for read operations, `workflows:write` for write operations

### Integrations

Discover and manage integrations.

```typescript
// List integrations with enhanced search
const integrations = await sdk.integrations.list({
  page: 1,
  limit: 20,
  type: 'action', // or 'trigger'
  search: 'slack',
  sortBy: 'name',
  sortOrder: 'asc'
});

// Get an integration
const integration = await sdk.integrations.get('slack');

// Get connections for an integration (requires connector access)
const connections = await sdk.integrations.getConnections('slack');
```

**Required Permissions**: `integrations:read`, and connector access for `getConnections()`

### Users

User management operations.

```typescript
// Get current user
const user = await sdk.users.getCurrent();

// Update current user
await sdk.users.update({
  name: 'New Name',
  email: 'new@example.com'
});
```

**Required Permissions**: `users:read` for `getCurrent()`, `users:write` for `update()`

### MCP (Model Context Protocol)

Access MCP resources.

```typescript
// List MCP resources
const resources = await sdk.mcp.listResources();
```

**Required Permissions**: `mcp:read`

### Recipes

Recipe management.

```typescript
// List recipes
const recipes = await sdk.recipes.list('filter', 'type');

// Get a recipe
const recipe = await sdk.recipes.get('recipe-id');
```

**Required Permissions**: `recipes:read`

## React Hooks

The SDK provides React hooks for easy integration in React applications.

### Setup

```tsx
import { LangslideProvider } from '@langslide/sdk/react';

function App() {
  return (
    <LangslideProvider
      config={{
        apiKey: process.env.REACT_APP_LANGSLIDE_API_KEY
      }}
    >
      <YourApp />
    </LangslideProvider>
  );
}
```

### useLangslide

Get the SDK instance.

```tsx
import { useLangslide } from '@langslide/sdk/react';

function MyComponent() {
  const sdk = useLangslide();
  // Use sdk directly
}
```

### useWorkflows

Manage workflows with automatic state management.

```tsx
import { useWorkflows } from '@langslide/sdk/react';

function WorkflowManager() {
  const {
    workflows,
    loading,
    error,
    pagination,
    createWorkflow,
    updateWorkflow,
    deleteWorkflow,
    triggerWorkflow,
    getWorkflow,
    refresh
  } = useWorkflows({
    status: 'active',
    limit: 20
  });

  return (
    <div>
      {workflows.map(w => (
        <div key={w.id}>
          <h3>{w.name}</h3>
          <button onClick={() => triggerWorkflow(w.id)}>Trigger</button>
        </div>
      ))}
    </div>
  );
}
```

### useIntegrations

Manage integrations.

```tsx
import { useIntegrations } from '@langslide/sdk/react';

function IntegrationList() {
  const {
    integrations,
    loading,
    error,
    getIntegration,
    getConnections,
    refresh
  } = useIntegrations({
    type: 'action'
  });

  // Use integrations...
}
```

## Enhanced Search

All list methods support enhanced search and filtering:

```typescript
// Text search
const results = await sdk.workflows.list({
  search: 'email automation'
});

// Sorting
const sorted = await sdk.workflows.list({
  sortBy: 'created_at',
  sortOrder: 'desc'
});

// Date filtering
const recent = await sdk.workflows.list({
  createdAfter: '2024-01-01',
  createdBefore: '2024-12-31'
});

// Tags filtering
const tagged = await sdk.workflows.list({
  tags: ['email', 'automation']
});

// Combined
const advanced = await sdk.workflows.list({
  search: 'slack',
  sortBy: 'name',
  sortOrder: 'asc',
  createdAfter: '2024-01-01',
  tags: ['integration']
});
```

## Permissions & Access Control

The SDK supports permission-based access control for API keys.

### Permission System

API keys can have different permission levels:

- **SDK Methods**: Control which API methods can be called
  - `workflows:read` - Read workflows
  - `workflows:write` - Create/update/delete workflows
  - `integrations:read` - Read integrations
  - `users:read` - Read user information
  - `users:write` - Update user information
  - `mcp:read` - Read MCP resources
  - `recipes:read` - Read recipes
  - `*` - All permissions

- **Connectors**: Control access to specific integrations
  - `["gmail", "slack"]` - Access to specific connectors
  - `["*"]` - Access to all connectors

### Using Permissions

```typescript
// Set API key (automatically validates and fetches permissions)
await sdk.setApiKey('your-api-key');

// Check permissions
const permissions = sdk.getPermissions();
console.log('SDK Methods:', permissions?.sdk_methods);
console.log('Connectors:', permissions?.connectors);

// Permission checks happen automatically
try {
  await sdk.workflows.create({ name: 'New Workflow' });
} catch (error) {
  if (error instanceof LangslidePermissionError) {
    console.error('Permission denied:', error.message);
    console.error('Required:', error.requiredPermission);
  }
}
```

### Connector Access

Connector names are normalized to lowercase for consistent matching:

```typescript
// These all work the same way:
await sdk.integrations.getConnections('google_sheets');
await sdk.integrations.getConnections('Google_Sheets');
await sdk.integrations.getConnections('GOOGLE_SHEETS');
```

**Note**: JWT-authenticated users (no API key) have full access and bypass permission checks.

## Error Handling

The SDK provides structured error classes for better error handling:

```typescript
import {
  LangslideError,
  LangslideAPIError,
  LangslideAuthError,
  LangslideValidationError,
  LangslidePermissionError
} from '@langslide/sdk';

try {
  await sdk.workflows.get('invalid-id');
} catch (error) {
  if (error instanceof LangslidePermissionError) {
    console.error('Permission Error:', error.message);
    console.error('Required:', error.requiredPermission);
  } else if (error instanceof LangslideAPIError) {
    console.error('API Error:', error.statusCode, error.message);
    console.error('Response:', error.response);
  } else if (error instanceof LangslideAuthError) {
    console.error('Auth Error:', error.message);
  } else if (error instanceof LangslideValidationError) {
    console.error('Validation Error:', error.message);
    console.error('Field:', error.field);
  } else if (error instanceof LangslideError) {
    console.error('SDK Error:', error.message);
  }
}
```

## TypeScript Support

The SDK is written in TypeScript and provides full type definitions:

```typescript
import {
  LangslideSDK,
  Workflow,
  Integration,
  Connection,
  ListOptions,
  PaginatedResponse
} from '@langslide/sdk';

const sdk = new LangslideSDK({ apiKey: 'key' });

const workflow: Workflow = await sdk.workflows.get('id');
const integration: Integration = await sdk.integrations.get('slack');
const workflows: PaginatedResponse<Workflow> = await sdk.workflows.list();
```

## Common Use Cases

### Workflow Automation

```typescript
async function automateWorkflow() {
  // Create workflow
  const workflow = await sdk.workflows.create({
    name: 'Daily Report',
    status: 'active'
  });

  // Trigger workflow with payload
  await sdk.workflows.trigger(workflow.id, {
    body: {
      date: new Date().toISOString(),
      reportType: 'daily'
    }
  });

  // Monitor usage
  const usage = await sdk.workflows.getUsage();
  console.log('Total executions:', usage.total);
}
```

### Integration Management

```typescript
async function manageIntegrations() {
  // Find Slack integration
  const integrations = await sdk.integrations.list({
    search: 'slack',
    type: 'action'
  });

  const slack = integrations.items[0];
  
  // Get connections
  const connections = await sdk.integrations.getConnections('slack');
  console.log('Slack connections:', connections);
}
```

### Advanced Search

```typescript
async function findWorkflows() {
  // Find active workflows created this month
  const workflows = await sdk.workflows.list({
    status: 'active',
    createdAfter: new Date(new Date().getFullYear(), new Date().getMonth(), 1).toISOString(),
    sortBy: 'created_at',
    sortOrder: 'desc',
    limit: 50
  });

  return workflows.items;
}
```

## API Reference

### WorkflowsAPI

| Method | Description | Permission |
|--------|-------------|------------|
| `list(options?)` | List workflows with pagination and filters | `workflows:read` |
| `get(id)` | Get workflow by ID | `workflows:read` |
| `create(payload)` | Create new workflow | `workflows:write` |
| `update(id, payload)` | Update workflow | `workflows:write` |
| `delete(id)` | Delete workflow | `workflows:write` |
| `trigger(id, payload?)` | Trigger workflow execution (returns `TriggerWorkflowResponse`) | `workflows:write` |
| `getUsage()` | Get usage statistics | `workflows:read` |

### IntegrationsAPI

| Method | Description | Permission |
|--------|-------------|------------|
| `list(options?)` | List integrations | `integrations:read` |
| `get(name)` | Get integration by name | `integrations:read` |
| `getConnections(name)` | Get connections for integration | `integrations:read` + connector access |

### UsersAPI

| Method | Description | Permission |
|--------|-------------|------------|
| `getCurrent()` | Get current user | `users:read` |
| `update(payload)` | Update current user | `users:write` |

### MCPAPI

| Method | Description | Permission |
|--------|-------------|------------|
| `listResources()` | List MCP resources | `mcp:read` |

### RecipesAPI

| Method | Description | Permission |
|--------|-------------|------------|
| `list(filter?, type?)` | List recipes | `recipes:read` |
| `get(id)` | Get recipe by ID | `recipes:read` |

### AuthAPI

| Method | Description | Permission |
|--------|-------------|------------|
| `validateAPIKey(key)` | Validate API key and fetch permissions | None |

## Troubleshooting

### CORS Issues

If you encounter CORS issues, ensure your `baseUrl` is correctly set:

```typescript
const sdk = new LangslideSDK({
  baseUrl: 'https://backend-api-306481332586.asia-southeast1.run.app'
});
```

### Authentication Errors

If you get 401 errors, verify your API key:

```typescript
// Re-validate API key
await sdk.setApiKey('your-api-key');

// Check permissions
const permissions = sdk.getPermissions();
if (!permissions) {
  console.error('API key validation failed');
}
```

### Permission Errors

Check your API key's permissions:

```typescript
const permissions = sdk.getPermissions();
if (permissions) {
  console.log('Available methods:', permissions.sdk_methods);
  console.log('Available connectors:', permissions.connectors);
}
```

### Build Issues

If you encounter build issues:

```bash
# Clean and rebuild
rm -rf dist node_modules
npm install
npm run build:all
```

## Contributing

We welcome contributions! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.

## License

MIT

## Support

- **GitHub Issues**: [https://github.com/langslide/sdk/issues](https://github.com/langslide/sdk/issues)
- **Documentation**: [https://docs.langslide.com/sdk](https://docs.langslide.com/sdk)
- **Email**: support@langslide.com

## Changelog

See [CHANGELOG.md](./CHANGELOG.md) for version history.