@unsent/sdk 0.25.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.cjs ADDED
@@ -0,0 +1,10 @@
1
+ /** @type {import("eslint").Linter.Config} */
2
+ module.exports = {
3
+ root: true,
4
+ extends: ["@unsent/eslint-config/library.js"],
5
+ parser: "@typescript-eslint/parser",
6
+ parserOptions: {
7
+ project: "./tsconfig.json",
8
+ tsconfigRootDir: __dirname,
9
+ },
10
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 unsent
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,328 @@
1
+ # @unsent/sdk SDK
2
+
3
+ ## Prerequisites
4
+
5
+ - [unsent API key](https://app.unsent.dev/dev-settings/api-keys)
6
+ - [Verified domain](https://app.unsent.dev/domains)
7
+
8
+ ## Installation
9
+
10
+ ### NPM
11
+
12
+ ```bash
13
+ npm install @unsent/sdk
14
+ ```
15
+
16
+ ### Yarn
17
+
18
+ ```bash
19
+ yarn add @unsent/sdk
20
+ ```
21
+
22
+ ### PNPM
23
+
24
+ ```bash
25
+ pnpm add @unsent/sdk
26
+ ```
27
+
28
+ ### Bun
29
+
30
+ ```bash
31
+ bun add @unsent/sdk
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ### Basic Setup
37
+
38
+ ```typescript
39
+ import { unsent } from "@unsent/sdk"
40
+
41
+ const client = new unsent("us_12345")
42
+ ```
43
+
44
+ ### Environment Variables
45
+
46
+ You can also set your API key using environment variables:
47
+
48
+ ```typescript
49
+ // Set UNSENT_API_KEY or UNSENT_API_KEY in your environment
50
+ // Then initialize without passing the key
51
+ const client = new unsent()
52
+ ```
53
+
54
+ ### Sending Emails
55
+
56
+ #### Simple Email
57
+
58
+ ```typescript
59
+ const { data, error } = await client.emails.send({
60
+ to: "hello@acme.com",
61
+ from: "hello@company.com",
62
+ subject: "unsent email",
63
+ html: "<p>unsent is the best open source product to send emails</p>",
64
+ text: "unsent is the best open source product to send emails",
65
+ })
66
+
67
+ if (error) {
68
+ console.error("Error:", error)
69
+ } else {
70
+ console.log("Email sent! ID:", data.id)
71
+ }
72
+ ```
73
+
74
+ #### Email with Attachments
75
+
76
+ ```typescript
77
+ const { data, error } = await client.emails.send({
78
+ to: "hello@acme.com",
79
+ from: "hello@company.com",
80
+ subject: "Email with attachment",
81
+ html: "<p>Please find the attachment below</p>",
82
+ attachments: [
83
+ {
84
+ filename: "document.pdf",
85
+ content: "base64-encoded-content-here",
86
+ },
87
+ ],
88
+ })
89
+ ```
90
+
91
+ #### Email with React Component
92
+
93
+ ```typescript
94
+ import { MyEmailTemplate } from "./templates/MyEmailTemplate"
95
+
96
+ const { data, error } = await client.emails.send({
97
+ to: "hello@acme.com",
98
+ from: "hello@company.com",
99
+ subject: "Email with React template",
100
+ react: <MyEmailTemplate name="John" />,
101
+ })
102
+ ```
103
+
104
+ #### Scheduled Email
105
+
106
+ ```typescript
107
+ const scheduledTime = new Date()
108
+ scheduledTime.setHours(scheduledTime.getHours() + 1) // Schedule for 1 hour from now
109
+
110
+ const { data, error } = await client.emails.send({
111
+ to: "hello@acme.com",
112
+ from: "hello@company.com",
113
+ subject: "Scheduled email",
114
+ html: "<p>This email was scheduled</p>",
115
+ scheduledAt: scheduledTime.toISOString(),
116
+ })
117
+ ```
118
+
119
+ #### Batch Emails
120
+
121
+ ```typescript
122
+ const emails = [
123
+ {
124
+ to: "user1@example.com",
125
+ from: "hello@company.com",
126
+ subject: "Hello User 1",
127
+ html: "<p>Welcome User 1</p>",
128
+ },
129
+ {
130
+ to: "user2@example.com",
131
+ from: "hello@company.com",
132
+ subject: "Hello User 2",
133
+ html: "<p>Welcome User 2</p>",
134
+ },
135
+ ]
136
+
137
+ const { data, error } = await client.emails.batch(emails)
138
+
139
+ if (error) {
140
+ console.error("Error:", error)
141
+ } else {
142
+ console.log(`Sent ${data.length} emails`)
143
+ }
144
+ ```
145
+
146
+ ### Managing Emails
147
+
148
+ #### Get Email Details
149
+
150
+ ```typescript
151
+ const { data, error } = await client.emails.get("email_id")
152
+
153
+ if (error) {
154
+ console.error("Error:", error)
155
+ } else {
156
+ console.log("Email status:", data.status)
157
+ }
158
+ ```
159
+
160
+ #### Update Email
161
+
162
+ ```typescript
163
+ const { data, error } = await client.emails.update("email_id", {
164
+ subject: "Updated subject",
165
+ html: "<p>Updated content</p>",
166
+ })
167
+ ```
168
+
169
+ #### Cancel Scheduled Email
170
+
171
+ ```typescript
172
+ const { data, error } = await client.emails.cancel("email_id")
173
+
174
+ if (error) {
175
+ console.error("Error:", error)
176
+ } else {
177
+ console.log("Email cancelled successfully")
178
+ }
179
+ ```
180
+
181
+ ### Managing Contacts
182
+
183
+ #### Create Contact
184
+
185
+ ```typescript
186
+ const { data, error } = await client.contacts.create("contact_book_id", {
187
+ email: "user@example.com",
188
+ firstName: "John",
189
+ lastName: "Doe",
190
+ metadata: {
191
+ company: "Acme Inc",
192
+ role: "Developer",
193
+ },
194
+ })
195
+ ```
196
+
197
+ #### Get Contact
198
+
199
+ ```typescript
200
+ const { data, error } = await client.contacts.get(
201
+ "contact_book_id",
202
+ "contact_id"
203
+ )
204
+ ```
205
+
206
+ #### Update Contact
207
+
208
+ ```typescript
209
+ const { data, error } = await client.contacts.update(
210
+ "contact_book_id",
211
+ "contact_id",
212
+ {
213
+ firstName: "Jane",
214
+ metadata: {
215
+ role: "Senior Developer",
216
+ },
217
+ }
218
+ )
219
+ ```
220
+
221
+ #### Upsert Contact
222
+
223
+ ```typescript
224
+ // Creates if doesn't exist, updates if exists
225
+ const { data, error } = await client.contacts.upsert(
226
+ "contact_book_id",
227
+ "contact_id",
228
+ {
229
+ email: "user@example.com",
230
+ firstName: "John",
231
+ lastName: "Doe",
232
+ }
233
+ )
234
+ ```
235
+
236
+ #### Delete Contact
237
+
238
+ ```typescript
239
+ const { data, error } = await client.contacts.delete(
240
+ "contact_book_id",
241
+ "contact_id"
242
+ )
243
+ ```
244
+
245
+ ### Error Handling
246
+
247
+ The SDK returns a consistent response structure with `data` and `error`:
248
+
249
+ ```typescript
250
+ const { data, error } = await client.emails.send({
251
+ to: "invalid-email",
252
+ from: "hello@company.com",
253
+ subject: "Test",
254
+ html: "<p>Test</p>",
255
+ })
256
+
257
+ if (error) {
258
+ console.error(`Error ${error.code}: ${error.message}`)
259
+ return
260
+ }
261
+
262
+ // Safe to use data here
263
+ console.log("Email sent:", data.id)
264
+ ```
265
+
266
+ ### TypeScript Support
267
+
268
+ The SDK is fully typed with TypeScript:
269
+
270
+ ```typescript
271
+ import { unsent } from "@unsent/sdk"
272
+
273
+ const client = new unsent("us_12345")
274
+
275
+ // Full type inference and autocomplete
276
+ const result = await client.emails.send({
277
+ to: "hello@acme.com",
278
+ from: "hello@company.com",
279
+ subject: "Typed email",
280
+ html: "<p>Fully typed!</p>",
281
+ })
282
+
283
+ // Type-safe access
284
+ if (result.data) {
285
+ const emailId: string = result.data.id
286
+ }
287
+ ```
288
+
289
+ ## API Reference
290
+
291
+ ### Client Methods
292
+
293
+ - `new unsent(key?, url?)` - Initialize the client
294
+
295
+ ### Email Methods
296
+
297
+ - `client.emails.send(payload)` - Send an email (alias for `create`)
298
+ - `client.emails.create(payload)` - Create and send an email
299
+ - `client.emails.batch(emails)` - Send multiple emails in batch (max 100)
300
+ - `client.emails.get(emailId)` - Get email details
301
+ - `client.emails.update(emailId, payload)` - Update a scheduled email
302
+ - `client.emails.cancel(emailId)` - Cancel a scheduled email
303
+
304
+ ### Contact Methods
305
+
306
+ - `client.contacts.create(bookId, payload)` - Create a contact
307
+ - `client.contacts.get(bookId, contactId)` - Get contact details
308
+ - `client.contacts.update(bookId, contactId, payload)` - Update a contact
309
+ - `client.contacts.upsert(bookId, contactId, payload)` - Upsert a contact
310
+ - `client.contacts.delete(bookId, contactId)` - Delete a contact
311
+
312
+ ## Features
313
+
314
+ - 🔐 **Type-safe** - Full TypeScript support with type inference
315
+ - ⚡ **Modern** - Built with ESM and async/await
316
+ - 🎨 **React Email** - Send emails using React components
317
+ - 📦 **Lightweight** - Minimal dependencies
318
+ - 🔄 **Batch sending** - Send up to 100 emails in a single request
319
+ - ⏰ **Scheduled emails** - Schedule emails for later delivery
320
+
321
+ ## Requirements
322
+
323
+ - Node.js 16+
324
+ - TypeScript 4.7+ (for TypeScript projects)
325
+
326
+ ## License
327
+
328
+ MIT