@send-kit/sdk
Version:
Official SendKit SDK for sending emails and managing subscriptions
438 lines (337 loc) • 11.6 kB
Markdown
# SendKit SDK
Official SDK for SendKit - Send beautiful emails with ease.
## Installation
```bash
npm install @sendkit/sdk
```
## Quick Start
```typescript
import { SendKit } from "@sendkit/sdk";
const sendkit = new SendKit({
apiKey: "pk_your_public_key",
secretKey: "sk_your_secret_key", // Optional for HMAC signing
});
// Send a marketing email
const result = await sendkit.sendMarketingEmail({
to: "user@example.com",
from: { name: "My App", email: "noreply@myapp.com" },
subject: "Welcome!",
html: "<h1>Welcome to our platform</h1>",
data: { firstName: "John" },
});
console.log("Job ID:", result.jobId);
```
## Features
- 🚀 **Zero Configuration** - No base URL required, automatically detects environment
- 📧 **Marketing Emails** - Send beautiful newsletters and marketing campaigns
- 💼 **Transactional Emails** - Send receipts, notifications, and important updates
- 📦 **Bulk Sending** - Send to multiple recipients efficiently (max 50 per request)
- 🔒 **Secure** - HMAC signing for sensitive operations
- 📊 **Quota Management** - Track and manage your email limits
- 🚦 **Rate Limiting** - Built-in rate limiting for API endpoints
- 📝 **TypeScript** - Full TypeScript support with type definitions
- 📨 **Newsletter Management** - Subscribe and unsubscribe users with ease
## API Reference
### Constructor
```typescript
new SendKit(config: SendKitConfig)
```
**Parameters:**
- `config.apiKey` (string, required) - Your SendKit public API key
- `config.secretKey` (string, optional) - Your SendKit secret key for HMAC signing
### Methods
#### `sendMarketingEmail(params)`
Send a marketing email to a single recipient.
```typescript
const result = await sendkit.sendMarketingEmail({
to: "user@example.com",
from: { name: "My App", email: "noreply@myapp.com" },
subject: "Welcome!",
html: "<h1>Welcome {{firstName}}!</h1>",
previewText: "Welcome to our platform",
data: { firstName: "John" },
scheduledAt: new Date("2024-01-15T10:00:00Z"), // Optional
newsletterId: "newsletter_123", // Optional
});
```
#### `sendTransactionalEmail(params)`
Send a transactional email with optional attachments.
```typescript
const result = await sendkit.sendTransactionalEmail({
to: "user@example.com",
from: { name: "My App", email: "noreply@myapp.com" },
subject: "Order Confirmation",
html: "<h1>Your order has been confirmed</h1>",
previewText: "Order confirmation",
// Optional: schedule this transactional email to be sent in the future
scheduledAt: new Date("2024-01-15T10:00:00Z"),
attachments: [
{
filename: "receipt.pdf",
content: Buffer.from("..."),
contentType: "application/pdf",
},
],
headers: {
"X-Custom-Header": "value",
},
});
```
#### `sendBulkEmails(params)`
Send marketing emails to multiple recipients. **Maximum 50 recipients per request.**
```typescript
const result = await sendkit.sendBulkEmails({
recipients: [
{ email: "user1@example.com", data: { name: "John" } },
{ email: "user2@example.com", data: { name: "Jane" } },
],
from: { name: "My App", email: "noreply@myapp.com" },
subject: "Newsletter",
html: "<h1>Hello {{name}}</h1>",
previewText: "Check out our latest updates",
data: { company: "My Company" }, // Global data for all recipients
scheduledAt: new Date("2024-01-15T10:00:00Z"), // Optional
newsletterId: "newsletter_123", // Optional
});
```
#### `getQuota()`
Get your current quota information.
```typescript
const quota = await sendkit.getQuota();
console.log(`You have ${quota.emailsRemaining} emails remaining`);
```
#### `subscribe(params)`
Subscribe a user to a newsletter.
```typescript
const result = await sendkit.subscribe({
email: "user@example.com",
name: "John", // optional
surname: "Doe", // optional
});
console.log(result.message); // "Successfully subscribed"
console.log(result.verified); // true if HMAC signed, false otherwise
```
#### `unsubscribe(params)`
Unsubscribe a user from a newsletter.
```typescript
const result = await sendkit.unsubscribe({
email: "user@example.com",
});
console.log(result.message); // "Successfully unsubscribed"
console.log(result.verified); // true if HMAC signed, false otherwise
```
## Rate Limiting
SendKit implements rate limiting to ensure fair usage and system stability. The following limits apply per API key:
### API Endpoint Limits
- **Marketing Emails** (`/api/send`): 60 requests per minute
- **Transactional Emails** (`/api/send-transactional`): 100 requests per minute
- **Bulk Sending** (`/api/send-bulk`): 10 requests per minute (max 50 recipients per request)
- **Quota Checking** (`/api/quota`): 120 requests per minute
- **Newsletter Subscription** (`/api/subscribe`): 120 requests per minute
- **Newsletter Unsubscription** (`/api/unsubscribe`): 120 requests per minute
### Rate Limit Headers
When rate limits are exceeded, the API returns a `429 Too Many Requests` status with additional headers:
```
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640995200
Retry-After: 60
```
### Handling Rate Limits
```typescript
try {
await sendkit.sendMarketingEmail(params);
} catch (error) {
if (error.statusCode === 429) {
const retryAfter = error.headers?.["retry-after"];
console.log(`Rate limited. Retry after ${retryAfter} seconds`);
}
}
```
## Security
### HMAC Signing
For additional security, you can sign your requests using your secret key:
```typescript
const sendkit = new SendKit({
apiKey: "pk_your_public_key",
secretKey: "sk_your_secret_key",
});
```
When a secret key is provided, the SDK automatically signs all requests with an HMAC signature.
### API Key Security
- Never commit API keys to version control
- Use environment variables
- Rotate keys regularly
- Use different keys for different environments
## Error Handling
The SDK throws custom error classes for different scenarios:
```typescript
try {
await sendkit.sendMarketingEmail(params);
} catch (error) {
if (error instanceof ValidationError) {
console.log("Invalid parameters:", error.message);
} else if (error instanceof QuotaExceededError) {
console.log("Email quota exceeded");
} else if (error instanceof SendKitError) {
console.log("API error:", error.statusCode, error.message);
}
}
```
## Examples
### Basic Marketing Email
```typescript
import { SendKit } from "@sendkit/sdk";
const sendkit = new SendKit({
apiKey: process.env.SENDKIT_API_KEY,
});
try {
const result = await sendkit.sendMarketingEmail({
to: "customer@example.com",
from: { name: "My Store", email: "noreply@mystore.com" },
subject: "Welcome to My Store!",
html: `
<h1>Welcome to My Store!</h1>
<p>We're excited to have you on board.</p>
<a href="https://mystore.com">Visit our store</a>
`,
previewText: "Welcome to My Store! We're excited to have you on board.",
data: {
firstName: "John",
storeUrl: "https://mystore.com",
},
});
console.log("Email sent! Job ID:", result.jobId);
} catch (error) {
console.error("Failed to send email:", error.message);
}
```
### Transactional Email with Attachment
```typescript
import { SendKit } from "@sendkit/sdk";
import fs from "fs";
const sendkit = new SendKit({
apiKey: process.env.SENDKIT_API_KEY,
secretKey: process.env.SENDKIT_SECRET_KEY,
});
try {
const receiptBuffer = fs.readFileSync("./receipt.pdf");
const result = await sendkit.sendTransactionalEmail({
to: "customer@example.com",
from: { name: "My Store", email: "orders@mystore.com" },
subject: "Order Confirmation #12345",
html: `
<h1>Thank you for your order!</h1>
<p>Your order #12345 has been confirmed.</p>
<p>Total: $99.99</p>
`,
previewText: "Your order #12345 has been confirmed. Total: $99.99",
attachments: [
{
filename: "receipt.pdf",
content: receiptBuffer,
contentType: "application/pdf",
},
],
});
console.log("Transactional email sent! Job ID:", result.jobId);
} catch (error) {
console.error("Failed to send transactional email:", error.message);
}
```
### Bulk Newsletter
```typescript
import { SendKit } from "@sendkit/sdk";
const sendkit = new SendKit({
apiKey: process.env.SENDKIT_API_KEY,
});
const subscribers = [
{ email: "john@example.com", data: { name: "John", plan: "premium" } },
{ email: "jane@example.com", data: { name: "Jane", plan: "basic" } },
{ email: "bob@example.com", data: { name: "Bob", plan: "premium" } },
];
try {
const result = await sendkit.sendBulkEmails({
recipients: subscribers,
from: { name: "My Newsletter", email: "newsletter@myapp.com" },
subject: "Weekly Newsletter - {{name}}",
html: `
<h1>Hello {{name}}!</h1>
<p>Here's your weekly update.</p>
<p>You're on the {{plan}} plan.</p>
<a href="https://myapp.com">Read more</a>
`,
previewText: "Hello {{name}}! Here's your weekly update.",
data: {
company: "My App",
website: "https://myapp.com",
},
newsletterId: "weekly_newsletter_2024_01",
});
console.log(
`Bulk email sent! ${result.totalRecipients} recipients, Job IDs:`,
result.jobIds
);
} catch (error) {
console.error("Failed to send bulk email:", error.message);
}
```
**Note:** The bulk sending API has a limit of **50 recipients per request**. For larger lists, you'll need to split them into multiple requests.
### Check Quota
```typescript
import { SendKit } from "@sendkit/sdk";
const sendkit = new SendKit({
apiKey: process.env.SENDKIT_API_KEY,
});
// Check quota
const quota = await sendkit.getQuota();
console.log(`Emails remaining: ${quota.emailsRemaining}/${quota.totalEmails}`);
console.log(`Reset date: ${quota.resetDate}`);
```
### Newsletter Management
```typescript
import { SendKit } from "@sendkit/sdk";
const sendkit = new SendKit({
apiKey: process.env.SENDKIT_API_KEY,
secretKey: process.env.SENDKIT_SECRET_KEY, // Optional for HMAC signing
});
// Subscribe a user
const subscribeResult = await sendkit.subscribe({
email: "user@example.com",
name: "John",
surname: "Doe",
});
console.log("Subscription result:", subscribeResult.message);
console.log("HMAC verified:", subscribeResult.verified);
// Later, unsubscribe the same user
const unsubscribeResult = await sendkit.unsubscribe({
email: "user@example.com",
});
console.log("Unsubscription result:", unsubscribeResult.message);
console.log("HMAC verified:", unsubscribeResult.verified);
```
## Troubleshooting
### Common Issues
1. **Invalid API Key**
- Ensure your API key starts with `pk_`
- Check that the key is enabled in your SendKit dashboard
- Verify you're using the correct environment (production vs staging)
2. **Quota Exceeded**
- Check your current quota with `getQuota()`
- Upgrade your plan if needed
- Wait for quota reset
3. **Invalid Email Format**
- Ensure recipient emails are valid
- Check sender email format
- Verify email addresses are properly formatted
4. **Network Issues**
- Check your internet connection
- Verify firewall settings
- Try again with exponential backoff
### Getting Help
- **Documentation**: [https://docs.send-kit.com](https://docs.send-kit.com)
- **GitHub Issues**: [https://github.com/your-org/sendkit/issues](https://github.com/your-org/sendkit/issues)
- **Support**: [support@send-kit.com](mailto:support@send-kit.com)
## License
MIT License - see [LICENSE](LICENSE) file for details.
## Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.