npm package: @hookstash/sdk
Description: Official HookStash SDK for JavaScript/TypeScript
Author: HookStash
Latest version: 0.1.22

# HookStash SDK

Official TypeScript SDK for the HookStash webhook management API.

## Installation

```bash
npm install @hookstash/sdk
# or
yarn add @hookstash/sdk
```

## Quick Start

```typescript
import { createClient } from '@hookstash/sdk';

const client = createClient({
  apiUrl: 'https://api.hookstash.io',
  apiKey: 'hk_live_your_api_key_here',
});

// List all endpoints
const { data: endpoints } = await client.endpoints.list();

// Create an endpoint
const { data: endpoint } = await client.endpoints.create({
  name: 'My Webhook Endpoint',
  slug: 'my-webhook',
});

// List webhooks
const { data: webhooks } = await client.webhooks.list(endpoint.id);
```

## Authentication

### API Key (Recommended for server-side)

```typescript
const client = createClient({
  apiUrl: 'https://api.hookstash.io',
  apiKey: 'hk_live_your_api_key_here',
});
```

### JWT Token (For browser/user sessions)

```typescript
const client = createClient({
  apiUrl: 'https://api.hookstash.io',
  authToken: 'your_jwt_access_token',
});

// Update token after refresh
client.setAuthToken(newToken);
```

## API Reference

### Endpoints

```typescript
// List all endpoints
const { data: endpoints } = await client.endpoints.list();

// Get a specific endpoint
const { data: endpoint } = await client.endpoints.get('endpoint-id');

// Create an endpoint
const { data: endpoint } = await client.endpoints.create({
  name: 'My Endpoint',
  slug: 'my-endpoint',
  description: 'Optional description',
});

// Update an endpoint
await client.endpoints.update('endpoint-id', { name: 'New Name' });

// Delete an endpoint
await client.endpoints.delete('endpoint-id');

// Activate/Deactivate
await client.endpoints.activate('endpoint-id');
await client.endpoints.deactivate('endpoint-id');

// Get endpoint stats (paid feature)
const { data: stats } = await client.endpoints.stats();
```

### Destinations

```typescript
// List destinations
const { data: destinations } = await client.destinations.list('endpoint-id');

// Create a destination
const { data: destination } = await client.destinations.create('endpoint-id', {
  name: 'My Backend',
  url: 'https://my-backend.com/webhooks',
  method: 'POST',
  retry_enabled: true,
  max_retries: 3,
  retry_strategy: 'EXPONENTIAL',
});

// Update a destination
await client.destinations.update('endpoint-id', 'destination-id', {
  is_active: false,
});

// Delete a destination
await client.destinations.delete('endpoint-id', 'destination-id');

// Update transformations (paid feature)
await client.destinations.updateTransformations('endpoint-id', 'destination-id', {
  transform_enabled: true,
  transformation_rules: [
    { type: 'RENAME_FIELD', config: { from: 'old', to: 'new' } },
  ],
});

// Test transformations
const { data: result } = await client.destinations.testTransformations(
  'endpoint-id',
  'destination-id',
  { payload: { old: 'value' } }
);

// Get forwarding attempts
const { data: attempts } = await client.destinations.getAttempts('endpoint-id', 'destination-id');
```

### Webhooks

```typescript
// List webhooks
const { data: webhooks } = await client.webhooks.list('endpoint-id', { page: 1, limit: 50 });

// Get a specific webhook
const { data: webhook } = await client.webhooks.get('webhook-id');

// Search webhooks
const { data: results } = await client.webhooks.search({
  query: 'order.created',
  endpoint_id: 'endpoint-id',
  start_date: '2024-01-01',
  end_date: '2024-12-31',
});

// Get webhook stats (paid feature)
const { data: stats } = await client.webhooks.stats('endpoint-id');

// Delete a webhook
await client.webhooks.delete('webhook-id');
```

### Replay

```typescript
// Replay a single webhook
const { data: result } = await client.replay.replayWebhook('webhook-id');

// Bulk replay (paid feature)
const { data: result } = await client.replay.bulkReplay({
  webhookIds: ['webhook-1', 'webhook-2'],
});

// Get replay history
const { data: history } = await client.replay.getReplayHistory('webhook-id');

// Get replay chain for an attempt
const { data: chain } = await client.replay.getReplayChain('attempt-id');
```

### Teams

```typescript
// List teams
const { data: teams } = await client.teams.list();

// Create a team
const { data: team } = await client.teams.create({
  name: 'My Team',
  slug: 'my-team',
});

// Get team members
const { data: members } = await client.teams.listMembers('team-id');

// Invite a member
const { data: invitation } = await client.teams.inviteMember('team-id', {
  email: 'user@example.com',
  role: 'member', // 'owner' | 'admin' | 'member'
});

// Accept an invitation (by token)
await client.teams.acceptInvitation('invitation-token');

// Update member role
await client.teams.updateMemberRole('team-id', 'user-id', { role: 'admin' });

// Remove a member
await client.teams.removeMember('team-id', 'user-id');

// Team endpoints
const { data: endpoints } = await client.teams.listEndpoints('team-id');
await client.teams.createEndpoint('team-id', { name: 'Team Endpoint' });
```

### Subscriptions

```typescript
// Get current subscription
const { data: { subscription, plan } } = await client.subscriptions.get();

// Get usage
const { data: usage } = await client.subscriptions.getUsage();
console.log(usage.endpoints.current, '/', usage.endpoints.limit);

// Get usage history
const { data: history } = await client.subscriptions.getUsageHistory({
  start_date: '2024-01-01',
  end_date: '2024-12-31',
});

// List available plans
const { data: plans } = await client.subscriptions.listPlans();

// Create checkout session
const { data: { checkout_url } } = await client.subscriptions.createCheckout({
  plan_id: 'pro',
  billing_cycle: 'monthly',
});

// Cancel subscription
await client.subscriptions.cancel();

// Change plan
await client.subscriptions.changePlan({
  new_plan_id: 'enterprise',
  billing_cycle: 'yearly',
});
```

### Custom Domains (Paid Feature)

```typescript
// List custom domains
const { data: domains } = await client.customDomains.list();

// Get domain for an endpoint
const { data: domain } = await client.customDomains.getForEndpoint('endpoint-id');

// Create a custom domain
const { data: domain } = await client.customDomains.create('endpoint-id', {
  domain: 'webhooks.example.com',
});

// Verify domain DNS
await client.customDomains.verify('domain-id');

// Delete domain
await client.customDomains.delete('domain-id');
```

### API Keys (Paid Feature)

```typescript
// List API keys
const { data: keys } = await client.apiKeys.list();

// Create an API key
const { data: key } = await client.apiKeys.create({
  name: 'Production Key',
  permissions: ['endpoints:read', 'webhooks:read'],
});
console.log('Save this key:', key.key); // Only shown once!

// Revoke an API key
await client.apiKeys.revoke('key-id');
```

### Real-time WebSocket

```typescript
// Create a listener
const listener = client.listen('endpoint-id');

// Listen for webhooks
listener.onWebhook((webhook) => {
  console.log('New webhook received:', webhook);
});

// Handle errors
listener.onError((error) => {
  console.error('WebSocket error:', error);
});

// Connect
listener.connect();

// Disconnect when done
listener.disconnect();
```

## Error Handling

```typescript
import { 
  HookStashError, 
  ValidationError, 
  AuthenticationError, 
  ForbiddenError, 
  NotFoundError,
  RateLimitError 
} from '@hookstash/sdk';

try {
  await client.endpoints.create({ name: '' });
} catch (error) {
  if (error instanceof ValidationError) {
    console.log('Validation errors:', error.errors);
  } else if (error instanceof AuthenticationError) {
    console.log('Not authenticated');
  } else if (error instanceof ForbiddenError) {
    console.log('Not authorized or feature not available');
  } else if (error instanceof NotFoundError) {
    console.log('Resource not found');
  } else if (error instanceof RateLimitError) {
    console.log('Rate limited, retry after:', error.retryAfter, 'seconds');
  } else if (error instanceof HookStashError) {
    console.log('API error:', error.message, error.statusCode);
  }
}
```

## Types

All types are exported from the package:

```typescript
import type {
  Endpoint,
  Destination,
  Webhook,
  Team,
  TeamMember,
  Plan,
  Subscription,
  Usage,
  CustomDomain,
  ApiKey,
  // ... and more
} from '@hookstash/sdk';
```

## License

MIT