@hookstash/sdk
v0.1.22
Published
Official HookStash SDK for JavaScript/TypeScript
Readme
HookStash SDK
Official TypeScript SDK for the HookStash webhook management API.
Installation
npm install @hookstash/sdk
# or
yarn add @hookstash/sdkQuick Start
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)
const client = createClient({
apiUrl: 'https://api.hookstash.io',
apiKey: 'hk_live_your_api_key_here',
});JWT Token (For browser/user sessions)
const client = createClient({
apiUrl: 'https://api.hookstash.io',
authToken: 'your_jwt_access_token',
});
// Update token after refresh
client.setAuthToken(newToken);API Reference
Endpoints
// 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
// 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
// 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
// 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
// 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: '[email protected]',
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
// 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)
// 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)
// 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
// 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
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:
import type {
Endpoint,
Destination,
Webhook,
Team,
TeamMember,
Plan,
Subscription,
Usage,
CustomDomain,
ApiKey,
// ... and more
} from '@hookstash/sdk';License
MIT
