listbee 0.5.0 → 0.6.0
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/README.md +187 -381
- package/dist/cjs/base-client.d.ts +9 -29
- package/dist/cjs/base-client.js +58 -14
- package/dist/cjs/base-client.js.map +1 -1
- package/dist/cjs/client.d.ts +17 -13
- package/dist/cjs/client.js +14 -11
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/errors.d.ts +12 -0
- package/dist/cjs/errors.js +31 -1
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/generated/api-types.d.ts +4089 -0
- package/dist/cjs/generated/api-types.js +7 -0
- package/dist/cjs/generated/api-types.js.map +1 -0
- package/dist/cjs/generated/enums.d.ts +94 -0
- package/dist/cjs/generated/enums.js +87 -0
- package/dist/cjs/generated/enums.js.map +1 -0
- package/dist/cjs/generated/operations.d.ts +233 -0
- package/dist/cjs/generated/operations.js +39 -0
- package/dist/cjs/generated/operations.js.map +1 -0
- package/dist/cjs/generated/types.d.ts +68 -0
- package/dist/cjs/{types/order.js → generated/types.js} +1 -4
- package/dist/cjs/generated/types.js.map +1 -0
- package/dist/cjs/index.d.ts +7 -13
- package/dist/cjs/index.js +22 -14
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/resources/account.d.ts +11 -6
- package/dist/cjs/resources/account.js +19 -8
- package/dist/cjs/resources/account.js.map +1 -1
- package/dist/cjs/resources/api-keys.d.ts +18 -4
- package/dist/cjs/resources/api-keys.js +17 -1
- package/dist/cjs/resources/api-keys.js.map +1 -1
- package/dist/cjs/resources/customers.d.ts +23 -0
- package/dist/cjs/resources/customers.js +44 -0
- package/dist/cjs/resources/customers.js.map +1 -0
- package/dist/cjs/resources/files.d.ts +27 -0
- package/dist/cjs/resources/files.js +37 -0
- package/dist/cjs/resources/files.js.map +1 -0
- package/dist/cjs/resources/index.d.ts +3 -1
- package/dist/cjs/resources/index.js +7 -3
- package/dist/cjs/resources/index.js.map +1 -1
- package/dist/cjs/resources/listings.d.ts +35 -35
- package/dist/cjs/resources/listings.js +51 -116
- package/dist/cjs/resources/listings.js.map +1 -1
- package/dist/cjs/resources/orders.d.ts +28 -16
- package/dist/cjs/resources/orders.js +43 -36
- package/dist/cjs/resources/orders.js.map +1 -1
- package/dist/cjs/resources/signup.d.ts +21 -9
- package/dist/cjs/resources/signup.js +20 -3
- package/dist/cjs/resources/signup.js.map +1 -1
- package/dist/cjs/resources/stripe.d.ts +18 -6
- package/dist/cjs/resources/stripe.js +18 -7
- package/dist/cjs/resources/stripe.js.map +1 -1
- package/dist/cjs/resources/webhooks.d.ts +59 -3
- package/dist/cjs/resources/webhooks.js +102 -21
- package/dist/cjs/resources/webhooks.js.map +1 -1
- package/dist/cjs/types/index.d.ts +4 -10
- package/dist/cjs/types/index.js +17 -9
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/shared.d.ts +25 -147
- package/dist/cjs/types/shared.js +12 -60
- package/dist/cjs/types/shared.js.map +1 -1
- package/dist/esm/base-client.d.ts +9 -29
- package/dist/esm/base-client.js +56 -12
- package/dist/esm/base-client.js.map +1 -1
- package/dist/esm/client.d.ts +17 -13
- package/dist/esm/client.js +14 -11
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/errors.d.ts +12 -0
- package/dist/esm/errors.js +27 -0
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/generated/api-types.d.ts +4089 -0
- package/dist/esm/generated/api-types.js +6 -0
- package/dist/esm/generated/api-types.js.map +1 -0
- package/dist/esm/generated/enums.d.ts +94 -0
- package/dist/esm/generated/enums.js +84 -0
- package/dist/esm/generated/enums.js.map +1 -0
- package/dist/esm/generated/operations.d.ts +233 -0
- package/dist/esm/generated/operations.js +36 -0
- package/dist/esm/generated/operations.js.map +1 -0
- package/dist/esm/generated/types.d.ts +68 -0
- package/dist/esm/generated/types.js +2 -0
- package/dist/esm/generated/types.js.map +1 -0
- package/dist/esm/index.d.ts +7 -13
- package/dist/esm/index.js +5 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/resources/account.d.ts +11 -6
- package/dist/esm/resources/account.js +19 -8
- package/dist/esm/resources/account.js.map +1 -1
- package/dist/esm/resources/api-keys.d.ts +18 -4
- package/dist/esm/resources/api-keys.js +17 -1
- package/dist/esm/resources/api-keys.js.map +1 -1
- package/dist/esm/resources/customers.d.ts +23 -0
- package/dist/esm/resources/customers.js +39 -0
- package/dist/esm/resources/customers.js.map +1 -0
- package/dist/esm/resources/files.d.ts +27 -0
- package/dist/esm/resources/files.js +33 -0
- package/dist/esm/resources/files.js.map +1 -0
- package/dist/esm/resources/index.d.ts +3 -1
- package/dist/esm/resources/index.js +3 -1
- package/dist/esm/resources/index.js.map +1 -1
- package/dist/esm/resources/listings.d.ts +35 -35
- package/dist/esm/resources/listings.js +50 -116
- package/dist/esm/resources/listings.js.map +1 -1
- package/dist/esm/resources/orders.d.ts +28 -16
- package/dist/esm/resources/orders.js +43 -36
- package/dist/esm/resources/orders.js.map +1 -1
- package/dist/esm/resources/signup.d.ts +21 -9
- package/dist/esm/resources/signup.js +20 -3
- package/dist/esm/resources/signup.js.map +1 -1
- package/dist/esm/resources/stripe.d.ts +18 -6
- package/dist/esm/resources/stripe.js +18 -7
- package/dist/esm/resources/stripe.js.map +1 -1
- package/dist/esm/resources/webhooks.d.ts +59 -3
- package/dist/esm/resources/webhooks.js +101 -21
- package/dist/esm/resources/webhooks.js.map +1 -1
- package/dist/esm/types/index.d.ts +4 -10
- package/dist/esm/types/index.js +2 -1
- package/dist/esm/types/index.js.map +1 -1
- package/dist/esm/types/shared.d.ts +25 -147
- package/dist/esm/types/shared.js +10 -59
- package/dist/esm/types/shared.js.map +1 -1
- package/package.json +4 -82
- package/dist/cjs/resources/stores.d.ts +0 -31
- package/dist/cjs/resources/stores.js +0 -67
- package/dist/cjs/resources/stores.js.map +0 -1
- package/dist/cjs/types/account.d.ts +0 -47
- package/dist/cjs/types/account.js +0 -6
- package/dist/cjs/types/account.js.map +0 -1
- package/dist/cjs/types/api-key.d.ts +0 -18
- package/dist/cjs/types/api-key.js +0 -6
- package/dist/cjs/types/api-key.js.map +0 -1
- package/dist/cjs/types/listing.d.ts +0 -187
- package/dist/cjs/types/listing.js +0 -6
- package/dist/cjs/types/listing.js.map +0 -1
- package/dist/cjs/types/order.d.ts +0 -75
- package/dist/cjs/types/order.js.map +0 -1
- package/dist/cjs/types/signup.d.ts +0 -24
- package/dist/cjs/types/signup.js +0 -6
- package/dist/cjs/types/signup.js.map +0 -1
- package/dist/cjs/types/store.d.ts +0 -70
- package/dist/cjs/types/store.js +0 -6
- package/dist/cjs/types/store.js.map +0 -1
- package/dist/cjs/types/stripe.d.ts +0 -12
- package/dist/cjs/types/stripe.js +0 -6
- package/dist/cjs/types/stripe.js.map +0 -1
- package/dist/cjs/types/webhook.d.ts +0 -88
- package/dist/cjs/types/webhook.js +0 -6
- package/dist/cjs/types/webhook.js.map +0 -1
- package/dist/esm/resources/stores.d.ts +0 -31
- package/dist/esm/resources/stores.js +0 -63
- package/dist/esm/resources/stores.js.map +0 -1
- package/dist/esm/types/account.d.ts +0 -47
- package/dist/esm/types/account.js +0 -5
- package/dist/esm/types/account.js.map +0 -1
- package/dist/esm/types/api-key.d.ts +0 -18
- package/dist/esm/types/api-key.js +0 -5
- package/dist/esm/types/api-key.js.map +0 -1
- package/dist/esm/types/listing.d.ts +0 -187
- package/dist/esm/types/listing.js +0 -5
- package/dist/esm/types/listing.js.map +0 -1
- package/dist/esm/types/order.d.ts +0 -75
- package/dist/esm/types/order.js +0 -5
- package/dist/esm/types/order.js.map +0 -1
- package/dist/esm/types/signup.d.ts +0 -24
- package/dist/esm/types/signup.js +0 -5
- package/dist/esm/types/signup.js.map +0 -1
- package/dist/esm/types/store.d.ts +0 -70
- package/dist/esm/types/store.js +0 -5
- package/dist/esm/types/store.js.map +0 -1
- package/dist/esm/types/stripe.d.ts +0 -12
- package/dist/esm/types/stripe.js +0 -5
- package/dist/esm/types/stripe.js.map +0 -1
- package/dist/esm/types/webhook.d.ts +0 -88
- package/dist/esm/types/webhook.js +0 -5
- package/dist/esm/types/webhook.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Official TypeScript SDK for the [ListBee API](https://listbee.so) — one API call to sell and deliver digital content.
|
|
4
4
|
|
|
5
|
+
- Zero runtime dependencies (native fetch, Node >= 18)
|
|
6
|
+
- Types generated from OpenAPI spec — zero drift
|
|
7
|
+
- Full error hierarchy (RFC 9457)
|
|
8
|
+
- Cursor-based pagination
|
|
9
|
+
- Retry with exponential backoff
|
|
10
|
+
- Idempotency support
|
|
11
|
+
|
|
5
12
|
## Install
|
|
6
13
|
|
|
7
14
|
```bash
|
|
@@ -19,42 +26,29 @@ import { ListBee } from 'listbee';
|
|
|
19
26
|
|
|
20
27
|
const client = new ListBee({ apiKey: 'lb_...' });
|
|
21
28
|
|
|
22
|
-
//
|
|
29
|
+
// Create a listing, set a deliverable, publish
|
|
23
30
|
const listing = await client.listings.create({
|
|
24
31
|
name: 'SEO Playbook',
|
|
25
|
-
price: 2900,
|
|
26
|
-
|
|
32
|
+
price: 2900, // $29.00 in cents
|
|
33
|
+
description: 'A comprehensive guide to modern SEO.',
|
|
27
34
|
});
|
|
28
|
-
console.log(listing.url); // https://buy.listbee.so/r7kq2xy9
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
name: 'Custom SEO Report',
|
|
33
|
-
price: 4900,
|
|
34
|
-
fulfillment: 'external',
|
|
35
|
-
checkout_schema: [
|
|
36
|
-
{ type: 'text', key: 'website_url', label: 'Your website URL', required: true },
|
|
37
|
-
],
|
|
36
|
+
await client.listings.setDeliverables(listing.id, {
|
|
37
|
+
url: 'https://example.com/seo-playbook.pdf',
|
|
38
38
|
});
|
|
39
|
+
|
|
40
|
+
const published = await client.listings.publish(listing.id);
|
|
41
|
+
console.log(published.url); // https://buy.listbee.so/r7kq2xy9
|
|
39
42
|
```
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
Or read from the environment:
|
|
42
45
|
|
|
43
46
|
```bash
|
|
44
47
|
export LISTBEE_API_KEY="lb_..."
|
|
45
48
|
```
|
|
46
49
|
|
|
47
50
|
```typescript
|
|
48
|
-
import { ListBee } from 'listbee';
|
|
49
|
-
|
|
50
51
|
const client = new ListBee(); // reads LISTBEE_API_KEY automatically
|
|
51
|
-
|
|
52
|
-
const listing = await client.listings.create({
|
|
53
|
-
name: 'SEO Playbook',
|
|
54
|
-
price: 2900,
|
|
55
|
-
content: 'https://example.com/seo-playbook.pdf',
|
|
56
|
-
});
|
|
57
|
-
console.log(listing.url);
|
|
58
52
|
```
|
|
59
53
|
|
|
60
54
|
## Authentication
|
|
@@ -62,145 +56,138 @@ console.log(listing.url);
|
|
|
62
56
|
Pass your API key explicitly or via the `LISTBEE_API_KEY` environment variable.
|
|
63
57
|
|
|
64
58
|
```typescript
|
|
65
|
-
import { ListBee } from 'listbee';
|
|
66
|
-
|
|
67
|
-
// Explicit key
|
|
68
59
|
const client = new ListBee({ apiKey: 'lb_...' });
|
|
69
|
-
|
|
70
|
-
// Environment variable (LISTBEE_API_KEY)
|
|
71
|
-
const client = new ListBee();
|
|
72
|
-
|
|
73
|
-
// process.env lookup
|
|
74
|
-
const client = new ListBee({ apiKey: process.env.LISTBEE_API_KEY });
|
|
60
|
+
const client = new ListBee(); // env var
|
|
75
61
|
```
|
|
76
62
|
|
|
77
|
-
The key is validated lazily —
|
|
78
|
-
|
|
79
|
-
API keys start with `lb_`. Get yours at [listbee.so](https://listbee.so).
|
|
63
|
+
The key is validated lazily — an `AuthenticationError` is raised only when you make the first API call. API keys start with `lb_`. Get yours at [listbee.so](https://listbee.so).
|
|
80
64
|
|
|
81
65
|
## Resources
|
|
82
66
|
|
|
67
|
+
| Resource | Methods |
|
|
68
|
+
|----------|---------|
|
|
69
|
+
| `listings` | `create`, `get`, `list`, `update`, `publish`, `setDeliverables`, `removeDeliverables`, `delete` |
|
|
70
|
+
| `orders` | `get`, `list`, `deliver`, `refund` |
|
|
71
|
+
| `customers` | `get`, `list` |
|
|
72
|
+
| `files` | `upload` |
|
|
73
|
+
| `webhooks` | `create`, `get`, `list`, `update`, `delete`, `listEvents`, `retryEvent`, `test`, `verify` |
|
|
74
|
+
| `account` | `get`, `update`, `delete` |
|
|
75
|
+
| `apiKeys` | `list`, `create`, `delete` |
|
|
76
|
+
| `signup` | `create`, `verify` |
|
|
77
|
+
| `stripe` | `connect`, `disconnect` |
|
|
78
|
+
|
|
83
79
|
### Listings
|
|
84
80
|
|
|
85
81
|
```typescript
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const client = new ListBee({ apiKey: 'lb_...' });
|
|
89
|
-
|
|
90
|
-
// Create — managed fulfillment (ListBee delivers the file)
|
|
91
|
-
const listing = await client.listings.create({
|
|
92
|
-
name: 'SEO Playbook',
|
|
93
|
-
price: 2900, // $29.00 in cents
|
|
94
|
-
content: 'https://example.com/seo-playbook.pdf', // file URL, redirect URL, or plain text
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// Create — external fulfillment (you deliver via webhooks)
|
|
98
|
-
const report = await client.listings.create({
|
|
99
|
-
name: 'Custom SEO Report',
|
|
100
|
-
price: 4900,
|
|
101
|
-
fulfillment: 'external',
|
|
102
|
-
checkout_schema: [
|
|
103
|
-
{ type: 'text', key: 'website_url', label: 'Your website URL', required: true },
|
|
104
|
-
{ type: 'select', key: 'priority', label: 'Priority', required: false, options: ['standard', 'rush'] },
|
|
105
|
-
],
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// Create — all optional params
|
|
82
|
+
// Create
|
|
109
83
|
const listing = await client.listings.create({
|
|
110
84
|
name: 'SEO Playbook 2026',
|
|
111
85
|
price: 2900,
|
|
112
|
-
content: 'https://example.com/seo-playbook.pdf',
|
|
113
86
|
description: 'A comprehensive guide to modern SEO techniques.',
|
|
114
87
|
tagline: 'Updated for 2026 algorithm changes',
|
|
115
88
|
highlights: ['50+ pages', 'Actionable tips', 'Free updates'],
|
|
116
|
-
cta: 'Get Instant Access',
|
|
89
|
+
cta: 'Get Instant Access',
|
|
117
90
|
cover_url: 'https://example.com/cover.png',
|
|
118
|
-
compare_at_price: 3900,
|
|
119
|
-
badges: ['Limited time', 'Best seller'],
|
|
120
|
-
cover_blur: 'auto', // "auto" | "true" | "false"
|
|
121
|
-
rating: 4.8,
|
|
122
|
-
rating_count: 1243,
|
|
123
|
-
reviews: [
|
|
124
|
-
{ name: 'Clara D.', rating: 5.0, content: 'Excellent quality content.' },
|
|
125
|
-
],
|
|
126
|
-
faqs: [
|
|
127
|
-
{ q: 'Is this for beginners?', a: 'Yes, completely beginner-friendly.' },
|
|
128
|
-
],
|
|
91
|
+
compare_at_price: 3900,
|
|
129
92
|
metadata: { source: 'n8n', campaign: 'launch-week' },
|
|
130
93
|
});
|
|
131
|
-
console.log(listing.id);
|
|
132
|
-
console.log(listing.url); // https://buy.listbee.so/m3pr5tw1
|
|
94
|
+
console.log(listing.id); // lst_r7kq2xy9m3pR5tW1
|
|
133
95
|
|
|
134
|
-
//
|
|
135
|
-
|
|
96
|
+
// Set deliverables (file, URL, or text)
|
|
97
|
+
await client.listings.setDeliverables(listing.id, {
|
|
98
|
+
url: 'https://example.com/seo-playbook.pdf',
|
|
99
|
+
});
|
|
136
100
|
|
|
137
|
-
//
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
console.log(listing.slug, listing.name);
|
|
141
|
-
}
|
|
101
|
+
// Publish
|
|
102
|
+
const published = await client.listings.publish(listing.id);
|
|
103
|
+
console.log(published.url); // https://buy.listbee.so/r7kq2xy9
|
|
142
104
|
|
|
143
|
-
//
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
105
|
+
// Get by ID
|
|
106
|
+
const listing = await client.listings.get('lst_r7kq2xy9m3pR5tW1');
|
|
107
|
+
|
|
108
|
+
// List — with filters
|
|
109
|
+
const page = await client.listings.list({
|
|
110
|
+
status: 'published',
|
|
111
|
+
limit: 20,
|
|
147
112
|
});
|
|
113
|
+
for (const l of page.data) {
|
|
114
|
+
console.log(l.id, l.name, l.status);
|
|
115
|
+
}
|
|
116
|
+
console.log(page.total_count); // total matching listings
|
|
148
117
|
|
|
149
|
-
//
|
|
150
|
-
await client.listings.
|
|
151
|
-
|
|
118
|
+
// Update
|
|
119
|
+
await client.listings.update('lst_r7kq2xy9m3pR5tW1', { price: 3900 });
|
|
120
|
+
|
|
121
|
+
// Remove deliverables (revert to external fulfillment)
|
|
122
|
+
await client.listings.removeDeliverables('lst_r7kq2xy9m3pR5tW1');
|
|
152
123
|
|
|
153
124
|
// Delete
|
|
154
|
-
await client.listings.delete('
|
|
125
|
+
await client.listings.delete('lst_r7kq2xy9m3pR5tW1');
|
|
155
126
|
```
|
|
156
127
|
|
|
157
128
|
### Orders
|
|
158
129
|
|
|
159
130
|
```typescript
|
|
160
|
-
// List
|
|
161
|
-
const page = await client.orders.list();
|
|
162
|
-
for (const order of page.data) {
|
|
163
|
-
console.log(order.id, order.status);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Filter by status, listing, date range
|
|
131
|
+
// List — with filters
|
|
167
132
|
const page = await client.orders.list({
|
|
168
133
|
status: 'paid',
|
|
169
|
-
|
|
134
|
+
buyer_email: 'buyer@example.com',
|
|
170
135
|
created_after: new Date('2026-03-01'),
|
|
171
|
-
created_before: '2026-03-31T23:59:59Z',
|
|
136
|
+
created_before: '2026-03-31T23:59:59Z',
|
|
172
137
|
});
|
|
138
|
+
console.log(page.total_count);
|
|
173
139
|
|
|
174
140
|
// Get by ID
|
|
175
141
|
const order = await client.orders.get('ord_9xM4kP7nR2qT5wY1');
|
|
176
|
-
console.log(order.
|
|
177
|
-
console.log(order.
|
|
178
|
-
console.log(order.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
// Fulfill an order — push content to the buyer (external fulfillment)
|
|
184
|
-
const fulfilled = await client.orders.fulfill('ord_9xM4kP7nR2qT5wY1', {
|
|
185
|
-
content: 'Your custom report is ready.',
|
|
142
|
+
console.log(order.status); // "pending" | "paid" | "fulfilled" | "canceled" | "failed"
|
|
143
|
+
console.log(order.checkout_data); // custom checkout field values
|
|
144
|
+
console.log(order.paid_at); // ISO 8601 timestamp
|
|
145
|
+
|
|
146
|
+
// Deliver — push content to the buyer (external fulfillment)
|
|
147
|
+
const fulfilled = await client.orders.deliver('ord_9xM4kP7nR2qT5wY1', {
|
|
148
|
+
content: 'Your AI-generated report is ready.',
|
|
186
149
|
content_type: 'text',
|
|
187
150
|
});
|
|
188
|
-
console.log(fulfilled.status);
|
|
189
|
-
console.log(fulfilled.fulfillment_status); // "fulfilled"
|
|
151
|
+
console.log(fulfilled.status); // "fulfilled"
|
|
190
152
|
|
|
191
|
-
//
|
|
192
|
-
await client.orders.
|
|
153
|
+
// Or with a URL
|
|
154
|
+
await client.orders.deliver('ord_9xM4kP7nR2qT5wY1', {
|
|
193
155
|
content_url: 'https://example.com/report.pdf',
|
|
194
156
|
});
|
|
195
157
|
|
|
196
|
-
//
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
158
|
+
// Refund
|
|
159
|
+
const refunded = await client.orders.refund('ord_9xM4kP7nR2qT5wY1');
|
|
160
|
+
console.log(refunded.status); // "canceled"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Customers
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// List customers
|
|
167
|
+
const page = await client.customers.list({ limit: 20, email: 'buyer@example.com' });
|
|
168
|
+
for (const c of page.data) {
|
|
169
|
+
console.log(c.id, c.email);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Get a customer
|
|
173
|
+
const customer = await client.customers.get('cus_7kQ2xY9mN3pR5tW1');
|
|
174
|
+
console.log(customer.email, customer.order_count);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Files
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { createReadStream } from 'fs';
|
|
181
|
+
|
|
182
|
+
// Upload a file (multipart, native FormData)
|
|
183
|
+
const file = await client.files.upload({
|
|
184
|
+
file: createReadStream('/path/to/report.pdf'),
|
|
185
|
+
filename: 'report.pdf',
|
|
201
186
|
});
|
|
202
|
-
console.log(
|
|
203
|
-
|
|
187
|
+
console.log(file.id); // use this ID in setDeliverables
|
|
188
|
+
|
|
189
|
+
// Then attach to a listing
|
|
190
|
+
await client.listings.setDeliverables(listing.id, { file_id: file.id });
|
|
204
191
|
```
|
|
205
192
|
|
|
206
193
|
### Webhooks
|
|
@@ -217,46 +204,28 @@ const webhook = await client.webhooks.create({
|
|
|
217
204
|
events: [
|
|
218
205
|
WebhookEventType.ORDER_PAID,
|
|
219
206
|
WebhookEventType.ORDER_FULFILLED,
|
|
220
|
-
WebhookEventType.
|
|
207
|
+
WebhookEventType.CUSTOMER_CREATED,
|
|
221
208
|
],
|
|
222
209
|
});
|
|
223
210
|
console.log(webhook.id); // wh_3mK8nP2qR5tW7xY1
|
|
224
|
-
console.log(webhook.secret); // HMAC signing key
|
|
211
|
+
console.log(webhook.secret); // HMAC signing key — save this
|
|
225
212
|
|
|
226
|
-
//
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
// List
|
|
233
|
-
const webhooks = await client.webhooks.list();
|
|
234
|
-
for (const wh of webhooks) {
|
|
235
|
-
console.log(wh.id, wh.name, wh.enabled);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Update — disable without deleting
|
|
239
|
-
await client.webhooks.update('wh_3mK8nP2qR5tW7xY1', { enabled: false });
|
|
240
|
-
|
|
241
|
-
// Update — change URL and events
|
|
242
|
-
await client.webhooks.update('wh_3mK8nP2qR5tW7xY1', {
|
|
243
|
-
url: 'https://example.com/webhooks/v2',
|
|
244
|
-
events: [WebhookEventType.ORDER_PAID],
|
|
213
|
+
// Verify an incoming webhook (HMAC-SHA256, uses crypto.subtle — no dependencies)
|
|
214
|
+
const isValid = await client.webhooks.verify({
|
|
215
|
+
payload: rawBodyString,
|
|
216
|
+
signature: req.headers['listbee-signature'],
|
|
217
|
+
secret: webhook.secret,
|
|
245
218
|
});
|
|
246
219
|
|
|
247
220
|
// List delivery events
|
|
248
|
-
const events = await client.webhooks.listEvents('wh_3mK8nP2qR5tW7xY1', {
|
|
249
|
-
status: 'failed',
|
|
250
|
-
});
|
|
251
|
-
for (const evt of events.data) {
|
|
252
|
-
console.log(evt.event_type, evt.status, evt.last_error);
|
|
253
|
-
}
|
|
221
|
+
const events = await client.webhooks.listEvents('wh_3mK8nP2qR5tW7xY1', { status: 'failed' });
|
|
254
222
|
|
|
255
|
-
//
|
|
256
|
-
|
|
257
|
-
console.log(test.success, test.status_code);
|
|
223
|
+
// Retry a failed event
|
|
224
|
+
await client.webhooks.retryEvent('wh_3mK8nP2qR5tW7xY1', 'evt_abc123');
|
|
258
225
|
|
|
259
|
-
//
|
|
226
|
+
// Update, test, delete
|
|
227
|
+
await client.webhooks.update('wh_3mK8nP2qR5tW7xY1', { enabled: false });
|
|
228
|
+
await client.webhooks.test('wh_3mK8nP2qR5tW7xY1');
|
|
260
229
|
await client.webhooks.delete('wh_3mK8nP2qR5tW7xY1');
|
|
261
230
|
```
|
|
262
231
|
|
|
@@ -265,15 +234,12 @@ await client.webhooks.delete('wh_3mK8nP2qR5tW7xY1');
|
|
|
265
234
|
```typescript
|
|
266
235
|
const account = await client.account.get();
|
|
267
236
|
console.log(account.id); // acc_7kQ2xY9mN3pR5tW1
|
|
268
|
-
console.log(account.email);
|
|
237
|
+
console.log(account.email);
|
|
269
238
|
console.log(account.plan); // free | growth | scale
|
|
270
239
|
console.log(account.readiness.operational);
|
|
271
240
|
|
|
272
|
-
// Update Google Analytics tracking
|
|
273
241
|
await client.account.update({ ga_measurement_id: 'G-XXXXXXXXXX' });
|
|
274
|
-
|
|
275
|
-
// Clear GA tracking
|
|
276
|
-
await client.account.update({ ga_measurement_id: null });
|
|
242
|
+
await client.account.delete();
|
|
277
243
|
```
|
|
278
244
|
|
|
279
245
|
### Signup
|
|
@@ -281,93 +247,28 @@ await client.account.update({ ga_measurement_id: null });
|
|
|
281
247
|
Agent self-service onboarding — no API key required:
|
|
282
248
|
|
|
283
249
|
```typescript
|
|
284
|
-
import { ListBee } from 'listbee';
|
|
285
|
-
|
|
286
250
|
const client = new ListBee(); // no API key needed
|
|
287
251
|
|
|
288
|
-
// Request a signup code
|
|
289
252
|
await client.signup.create({ email: 'seller@example.com' });
|
|
290
253
|
|
|
291
|
-
|
|
292
|
-
const result = await client.signup.verify({
|
|
293
|
-
email: 'seller@example.com',
|
|
294
|
-
code: '123456',
|
|
295
|
-
});
|
|
254
|
+
const result = await client.signup.verify({ email: 'seller@example.com', code: '123456' });
|
|
296
255
|
console.log(result.api_key); // lb_... (one-time display)
|
|
297
256
|
```
|
|
298
257
|
|
|
299
258
|
### API keys
|
|
300
259
|
|
|
301
260
|
```typescript
|
|
302
|
-
// List all API keys
|
|
303
261
|
const keys = await client.apiKeys.list();
|
|
304
|
-
for (const key of keys) {
|
|
305
|
-
console.log(key.id, key.name);
|
|
306
|
-
}
|
|
307
262
|
|
|
308
|
-
// Create a new key — the key value is only shown once
|
|
309
263
|
const newKey = await client.apiKeys.create({ name: 'CI pipeline' });
|
|
310
264
|
console.log(newKey.key); // lb_... (save this immediately)
|
|
311
265
|
|
|
312
|
-
// Delete a key
|
|
313
266
|
await client.apiKeys.delete('lbk_7kQ2xY9mN3pR5tW1');
|
|
314
267
|
```
|
|
315
268
|
|
|
316
|
-
### Stores
|
|
317
|
-
|
|
318
|
-
```typescript
|
|
319
|
-
// Create a store
|
|
320
|
-
const store = await client.stores.create({ handle: 'fitness-brand', name: 'Fitness Brand' });
|
|
321
|
-
console.log(store.id); // str_7kQ2xY9mN3pR5tW1vB8a
|
|
322
|
-
console.log(store.handle); // fitness-brand
|
|
323
|
-
|
|
324
|
-
// List all stores
|
|
325
|
-
const stores = await client.stores.list();
|
|
326
|
-
for (const s of stores.data) {
|
|
327
|
-
console.log(s.handle, s.display_name);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// Get a store
|
|
331
|
-
const store = await client.stores.get('str_7kQ2xY9mN3pR5tW1vB8a');
|
|
332
|
-
|
|
333
|
-
// Update a store
|
|
334
|
-
const updated = await client.stores.update('str_7kQ2xY9mN3pR5tW1vB8a', {
|
|
335
|
-
name: 'Fitness Pro',
|
|
336
|
-
bio: 'Premium fitness content',
|
|
337
|
-
social_links: ['https://twitter.com/fitnesspro'],
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
// Delete a store
|
|
341
|
-
await client.stores.delete('str_7kQ2xY9mN3pR5tW1vB8a');
|
|
342
|
-
|
|
343
|
-
// Connect Stripe — returns a URL to redirect the user to
|
|
344
|
-
const session = await client.stores.connectStripe('str_7kQ2xY9mN3pR5tW1vB8a');
|
|
345
|
-
console.log(session.url); // redirect seller here
|
|
346
|
-
|
|
347
|
-
// Custom domains
|
|
348
|
-
const domain = await client.stores.setDomain('str_7kQ2xY9mN3pR5tW1vB8a', { domain: 'fitness.com' });
|
|
349
|
-
console.log(domain.cname_target); // buy.listbee.so — point your CNAME here
|
|
350
|
-
|
|
351
|
-
const verified = await client.stores.verifyDomain('str_7kQ2xY9mN3pR5tW1vB8a');
|
|
352
|
-
console.log(verified.status); // "verified" or "pending"
|
|
353
|
-
|
|
354
|
-
await client.stores.removeDomain('str_7kQ2xY9mN3pR5tW1vB8a');
|
|
355
|
-
|
|
356
|
-
// Create a listing in a specific store
|
|
357
|
-
const listing = await client.listings.create({
|
|
358
|
-
name: 'SEO Playbook',
|
|
359
|
-
price: 2900,
|
|
360
|
-
content: 'https://example.com/seo-playbook.pdf',
|
|
361
|
-
store_id: 'str_7kQ2xY9mN3pR5tW1vB8a',
|
|
362
|
-
});
|
|
363
|
-
```
|
|
364
|
-
|
|
365
269
|
### Stripe
|
|
366
270
|
|
|
367
271
|
```typescript
|
|
368
|
-
// Set your Stripe secret key
|
|
369
|
-
await client.stripe.setKey({ secretKey: 'sk_live_...' });
|
|
370
|
-
|
|
371
272
|
// Generate a Stripe Connect onboarding link
|
|
372
273
|
const connect = await client.stripe.connect();
|
|
373
274
|
console.log(connect.url); // redirect seller here
|
|
@@ -378,75 +279,67 @@ await client.stripe.disconnect();
|
|
|
378
279
|
|
|
379
280
|
## Fulfillment modes
|
|
380
281
|
|
|
381
|
-
ListBee
|
|
382
|
-
|
|
383
|
-
- **Managed** — ListBee delivers digital content automatically (files, URLs, text). Set `content` when creating a listing.
|
|
384
|
-
- **External** — ListBee fires `order.paid` webhook, your app handles delivery. Use `orders.fulfill()` to push content back, or `orders.ship()` for physical goods.
|
|
282
|
+
- **Managed** — ListBee delivers digital content automatically. Call `setDeliverables()` on the listing, then `publish()`.
|
|
283
|
+
- **External** — ListBee fires `order.paid` webhook, your app handles delivery. Call `orders.deliver()` to push content back.
|
|
385
284
|
|
|
386
285
|
```typescript
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
// Fulfill externally — push generated content
|
|
398
|
-
await client.orders.fulfill('ord_...', {
|
|
399
|
-
content: 'Your AI-generated report...',
|
|
400
|
-
content_type: 'text',
|
|
286
|
+
// External fulfillment — AI-generated content
|
|
287
|
+
const listing = await client.listings.create({
|
|
288
|
+
name: 'Custom SEO Report',
|
|
289
|
+
price: 4900,
|
|
290
|
+
fulfillment: 'external',
|
|
291
|
+
checkout_schema: [
|
|
292
|
+
{ type: 'text', key: 'website_url', label: 'Your website URL', required: true },
|
|
293
|
+
],
|
|
401
294
|
});
|
|
295
|
+
await client.listings.publish(listing.id);
|
|
402
296
|
|
|
403
|
-
//
|
|
404
|
-
await client.orders.
|
|
405
|
-
|
|
406
|
-
|
|
297
|
+
// On order.paid webhook:
|
|
298
|
+
await client.orders.deliver(order.id, {
|
|
299
|
+
content: generatedReport,
|
|
300
|
+
content_type: 'text',
|
|
407
301
|
});
|
|
408
302
|
```
|
|
409
303
|
|
|
410
304
|
## Readiness system
|
|
411
305
|
|
|
412
|
-
Every listing and account includes a `readiness` field
|
|
413
|
-
|
|
414
|
-
- `listing.readiness.sellable` — `true` when buyers can complete a purchase
|
|
415
|
-
- `account.readiness.operational` — `true` when the account can sell
|
|
416
|
-
|
|
417
|
-
When `false`, an `actions` array explains what's needed and how to resolve each item. The `next` field points to the highest-priority action (prefers `kind: api`).
|
|
306
|
+
Every listing and account includes a `readiness` field.
|
|
418
307
|
|
|
419
308
|
```typescript
|
|
420
|
-
import { ActionKind } from 'listbee';
|
|
421
|
-
|
|
422
309
|
const account = await client.account.get();
|
|
423
310
|
if (!account.readiness.operational) {
|
|
424
311
|
for (const action of account.readiness.actions) {
|
|
425
|
-
if (action.kind ===
|
|
312
|
+
if (action.kind === 'api') {
|
|
426
313
|
console.log(`API action: ${action.code} -> ${action.resolve.endpoint}`);
|
|
427
314
|
} else {
|
|
428
315
|
console.log(`Manual step: ${action.code} -> ${action.resolve.url}`);
|
|
429
316
|
}
|
|
430
317
|
}
|
|
431
|
-
console.log(`Next action: ${account.readiness.next}`);
|
|
432
318
|
}
|
|
433
319
|
```
|
|
434
320
|
|
|
435
|
-
##
|
|
321
|
+
## Idempotency
|
|
322
|
+
|
|
323
|
+
Pass `idempotencyKey` to any mutating request. Same key within 24h returns the cached response:
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
await client.listings.create(
|
|
327
|
+
{ name: 'SEO Playbook', price: 2900 },
|
|
328
|
+
{ idempotencyKey: 'create-listing-campaign-2026' },
|
|
329
|
+
);
|
|
330
|
+
```
|
|
436
331
|
|
|
437
|
-
|
|
332
|
+
## Pagination
|
|
438
333
|
|
|
439
334
|
```typescript
|
|
440
|
-
// First page
|
|
441
335
|
const page = await client.listings.list({ limit: 10 });
|
|
442
|
-
console.log(page.data);
|
|
443
|
-
console.log(page.has_more);
|
|
444
|
-
console.log(page.cursor);
|
|
336
|
+
console.log(page.data); // ListingResponse[]
|
|
337
|
+
console.log(page.has_more); // true if more pages exist
|
|
338
|
+
console.log(page.cursor); // pass to next call
|
|
339
|
+
console.log(page.total_count); // total matching items
|
|
445
340
|
|
|
446
|
-
// Fetch next page
|
|
447
341
|
if (page.has_more) {
|
|
448
342
|
const nextPage = await client.listings.list({ limit: 10, cursor: page.cursor });
|
|
449
|
-
console.log(nextPage.data);
|
|
450
343
|
}
|
|
451
344
|
```
|
|
452
345
|
|
|
@@ -454,186 +347,99 @@ if (page.has_more) {
|
|
|
454
347
|
|
|
455
348
|
```
|
|
456
349
|
ListBeeError
|
|
457
|
-
├── APIConnectionError
|
|
458
|
-
├── APITimeoutError
|
|
459
|
-
└── APIStatusError
|
|
460
|
-
├──
|
|
461
|
-
├──
|
|
462
|
-
├──
|
|
463
|
-
├──
|
|
464
|
-
├──
|
|
465
|
-
|
|
350
|
+
├── APIConnectionError network error — request never reached the server
|
|
351
|
+
├── APITimeoutError request timed out
|
|
352
|
+
└── APIStatusError server returned 4xx/5xx
|
|
353
|
+
├── BadRequestError 400
|
|
354
|
+
├── AuthenticationError 401
|
|
355
|
+
├── ForbiddenError 403
|
|
356
|
+
├── NotFoundError 404
|
|
357
|
+
├── ConflictError 409
|
|
358
|
+
├── PayloadTooLargeError 413
|
|
359
|
+
├── ValidationError 422
|
|
360
|
+
├── RateLimitError 429
|
|
361
|
+
└── InternalServerError 500+
|
|
466
362
|
```
|
|
467
363
|
|
|
468
|
-
Catch specific errors:
|
|
469
|
-
|
|
470
364
|
```typescript
|
|
471
|
-
import {
|
|
472
|
-
ListBee,
|
|
473
|
-
AuthenticationError,
|
|
474
|
-
NotFoundError,
|
|
475
|
-
RateLimitError,
|
|
476
|
-
ValidationError,
|
|
477
|
-
APIConnectionError,
|
|
478
|
-
APITimeoutError,
|
|
479
|
-
APIStatusError,
|
|
480
|
-
} from 'listbee';
|
|
481
|
-
|
|
482
|
-
const client = new ListBee({ apiKey: 'lb_...' });
|
|
365
|
+
import { NotFoundError, AuthenticationError, RateLimitError, ErrorCode } from 'listbee';
|
|
483
366
|
|
|
484
367
|
try {
|
|
485
|
-
|
|
368
|
+
await client.listings.get('lst_does-not-exist');
|
|
486
369
|
} catch (e) {
|
|
487
370
|
if (e instanceof NotFoundError) {
|
|
488
371
|
console.log(e.status); // 404
|
|
489
|
-
console.log(e.code); //
|
|
372
|
+
console.log(e.code); // ErrorCode value
|
|
490
373
|
console.log(e.detail); // human-readable explanation
|
|
491
|
-
} else if (e instanceof AuthenticationError) {
|
|
492
|
-
console.log('Invalid API key');
|
|
493
374
|
} else if (e instanceof RateLimitError) {
|
|
494
|
-
console.log(`Rate limited. Resets at ${e.reset}
|
|
495
|
-
} else if (e instanceof ValidationError) {
|
|
496
|
-
console.log(`Bad request — field: ${e.param}, detail: ${e.detail}`);
|
|
497
|
-
} else if (e instanceof APIConnectionError) {
|
|
498
|
-
console.log('Network error — check your connection');
|
|
499
|
-
} else if (e instanceof APITimeoutError) {
|
|
500
|
-
console.log('Request timed out');
|
|
501
|
-
} else if (e instanceof APIStatusError) {
|
|
502
|
-
console.log(`API error ${e.status}: ${e.detail}`);
|
|
375
|
+
console.log(`Rate limited. Resets at ${e.reset}`);
|
|
503
376
|
}
|
|
504
377
|
}
|
|
505
378
|
```
|
|
506
379
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
| Attribute | Type | Description |
|
|
510
|
-
|-----------|------|-------------|
|
|
511
|
-
| `status` | `number` | HTTP status code |
|
|
512
|
-
| `code` | `string` | Machine-readable error code |
|
|
513
|
-
| `detail` | `string` | Specific explanation |
|
|
514
|
-
| `title` | `string` | Short, stable error category label |
|
|
515
|
-
| `type` | `string` | URI identifying the error type |
|
|
516
|
-
| `param` | `string \| null` | Request field that caused the error |
|
|
517
|
-
|
|
518
|
-
`RateLimitError` additionally exposes `limit`, `remaining`, and `reset` (parsed from response headers).
|
|
380
|
+
All `APIStatusError` subclasses expose: `status`, `code` (`ErrorCode`), `detail`, `title`, `type`, `param`.
|
|
519
381
|
|
|
520
382
|
## Configuration
|
|
521
383
|
|
|
522
384
|
```typescript
|
|
523
|
-
import { ListBee } from 'listbee';
|
|
524
|
-
|
|
525
385
|
const client = new ListBee({
|
|
526
386
|
apiKey: 'lb_...',
|
|
527
|
-
timeoutMs: 60_000,
|
|
387
|
+
timeoutMs: 60_000, // default: 30000
|
|
528
388
|
maxRetries: 5, // default: 3; retries on 429/500/502/503/504
|
|
529
|
-
baseUrl: 'https://api.listbee.so', //
|
|
530
|
-
});
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
`listings.create()` uses a default timeout of **120 seconds** because cover image processing can take longer. Pass `timeoutMs` to override:
|
|
534
|
-
|
|
535
|
-
```typescript
|
|
536
|
-
const listing = await client.listings.create({
|
|
537
|
-
name: 'Quick listing',
|
|
538
|
-
price: 999,
|
|
539
|
-
content: 'https://example.com/file.pdf',
|
|
540
|
-
timeoutMs: 30_000, // override the 120s default for this call
|
|
389
|
+
baseUrl: 'https://api.listbee.so', // override for testing
|
|
541
390
|
});
|
|
542
391
|
```
|
|
543
392
|
|
|
544
|
-
## Types
|
|
393
|
+
## Types
|
|
545
394
|
|
|
546
|
-
All types are importable
|
|
395
|
+
All types are importable from `listbee`:
|
|
547
396
|
|
|
548
397
|
```typescript
|
|
549
398
|
import {
|
|
550
|
-
// Client
|
|
551
399
|
ListBee,
|
|
552
400
|
CursorPage,
|
|
401
|
+
ErrorCode,
|
|
553
402
|
|
|
554
403
|
// Response types
|
|
555
404
|
type ListingResponse,
|
|
556
405
|
type OrderResponse,
|
|
406
|
+
type CustomerResponse,
|
|
407
|
+
type FileResponse,
|
|
557
408
|
type WebhookResponse,
|
|
558
409
|
type AccountResponse,
|
|
559
410
|
type ApiKeyResponse,
|
|
560
411
|
type SignupResponse,
|
|
561
412
|
type VerifyResponse,
|
|
562
|
-
type StripeConnectSessionResponse,
|
|
563
|
-
type StoreResponse,
|
|
564
|
-
type StoreListResponse,
|
|
565
|
-
type DomainResponse,
|
|
566
413
|
type WebhookEventResponse,
|
|
567
414
|
type WebhookTestResponse,
|
|
568
415
|
type CheckoutField,
|
|
569
|
-
type ShippingAddress,
|
|
570
|
-
|
|
571
|
-
// Param types
|
|
572
|
-
type FulfillOrderParams,
|
|
573
|
-
type ShipOrderParams,
|
|
574
|
-
|
|
575
|
-
// Enums (runtime values)
|
|
576
|
-
DeliverableType, // "file" | "url" | "text"
|
|
577
|
-
FulfillmentMode, // "managed" | "external"
|
|
578
|
-
CheckoutFieldType, // "address" | "text" | "select" | "date"
|
|
579
|
-
OrderStatus, // "pending" | "paid" | "fulfilled" | "canceled" | "failed"
|
|
580
|
-
FulfillmentStatus, // "pending" | "shipped" | "fulfilled"
|
|
581
|
-
WebhookEventType, // "order.paid" | "order.fulfilled" | "order.shipped" | ...
|
|
582
|
-
ActionCode, // "set_stripe_key" | "connect_stripe" | "configure_webhook" | ...
|
|
583
|
-
ActionKind, // "api" | "human"
|
|
584
416
|
|
|
585
|
-
//
|
|
586
|
-
|
|
417
|
+
// Enums
|
|
418
|
+
DeliverableType, // "file" | "url" | "text"
|
|
419
|
+
FulfillmentMode, // "managed" | "external"
|
|
420
|
+
ListingStatus, // "draft" | "published"
|
|
421
|
+
OrderStatus, // "pending" | "paid" | "fulfilled" | "canceled" | "failed"
|
|
422
|
+
WebhookEventType,
|
|
423
|
+
ActionCode,
|
|
424
|
+
ActionKind,
|
|
587
425
|
|
|
588
426
|
// Errors
|
|
589
427
|
ListBeeError,
|
|
590
428
|
APIStatusError,
|
|
591
429
|
APIConnectionError,
|
|
592
430
|
APITimeoutError,
|
|
431
|
+
BadRequestError,
|
|
593
432
|
AuthenticationError,
|
|
433
|
+
ForbiddenError,
|
|
594
434
|
NotFoundError,
|
|
595
435
|
ConflictError,
|
|
436
|
+
PayloadTooLargeError,
|
|
596
437
|
ValidationError,
|
|
597
438
|
RateLimitError,
|
|
598
439
|
InternalServerError,
|
|
599
440
|
} from 'listbee';
|
|
600
441
|
```
|
|
601
442
|
|
|
602
|
-
Enums are `as const` objects — use them to avoid magic strings:
|
|
603
|
-
|
|
604
|
-
```typescript
|
|
605
|
-
import { DeliverableType, WebhookEventType, FulfillmentMode } from 'listbee';
|
|
606
|
-
|
|
607
|
-
// Check deliverable type
|
|
608
|
-
if (listing.deliverable_type === DeliverableType.FILE) {
|
|
609
|
-
console.log('Delivers a file');
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
// Check fulfillment mode
|
|
613
|
-
if (listing.fulfillment === FulfillmentMode.EXTERNAL) {
|
|
614
|
-
console.log('External fulfillment — handle delivery yourself');
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// Subscribe to specific events
|
|
618
|
-
const webhook = await client.webhooks.create({
|
|
619
|
-
name: 'Orders only',
|
|
620
|
-
url: 'https://example.com/hooks',
|
|
621
|
-
events: [
|
|
622
|
-
WebhookEventType.ORDER_PAID,
|
|
623
|
-
WebhookEventType.ORDER_FULFILLED,
|
|
624
|
-
],
|
|
625
|
-
});
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
## Tree-shaking
|
|
629
|
-
|
|
630
|
-
Import individual resources for smaller bundles:
|
|
631
|
-
|
|
632
|
-
```typescript
|
|
633
|
-
import { WebhooksResource } from 'listbee/webhooks';
|
|
634
|
-
import { OrdersResource } from 'listbee/orders';
|
|
635
|
-
```
|
|
636
|
-
|
|
637
443
|
## Requirements
|
|
638
444
|
|
|
639
445
|
- Node.js >= 18
|