vybekiit 0.7.33 → 0.7.34

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.
@@ -0,0 +1,349 @@
1
+ # Inboxes
2
+
3
+ An inbox sends and receives email at one address on your domain. Received and sent emails group into threads. Each thread is in one folder and can carry labels. Drafts hold unsent emails, and agent settings tell an AI agent how to handle the threads of the inbox.
4
+
5
+ Inboxes need Node.js `resend` 6.33.0 or later, or Python `resend` 2.50.0 or later.
6
+
7
+ If an agent acts on the content of received emails, also install the `agent-email-inbox` skill. It covers the security levels for untrusted input.
8
+
9
+ ## SDK Methods
10
+
11
+ | Operation | Node.js | Python |
12
+ |-----------|---------|--------|
13
+ | Create inbox | `resend.inboxes.create(params)` | `resend.Inboxes.create(params)` |
14
+ | List inboxes | `resend.inboxes.list(params?)` | `resend.Inboxes.list(params?)` |
15
+ | Get inbox | `resend.inboxes.get(idOrEmail)` | `resend.Inboxes.get(inbox_id)` |
16
+ | Update inbox | `resend.inboxes.update(id, params)` | `resend.Inboxes.update(params)`, `id` inside params |
17
+ | Delete inbox | `resend.inboxes.remove(id)` | `resend.Inboxes.remove(inbox_id)` |
18
+ | Get agent settings | `resend.inboxes.agent.get({ inboxId })` | `resend.Inboxes.Agent.get(inbox_id)` |
19
+ | Update agent settings | `resend.inboxes.agent.update({ inboxId, ...params })` | `resend.Inboxes.Agent.update(params)`, `inbox_id` inside params |
20
+ | List labels | `resend.inboxes.labels.list({ inboxId })` | `resend.Inboxes.Labels.list(inbox_id)` |
21
+ | Create label | `resend.inboxes.labels.create({ inboxId, ...params })` | `resend.Inboxes.Labels.create(params)`, `inbox_id` inside params |
22
+ | Update label | `resend.inboxes.labels.update({ inboxId, labelId, ...params })` | `resend.Inboxes.Labels.update(params)`, `inbox_id` and `id` inside params |
23
+ | Delete label | `resend.inboxes.labels.remove({ inboxId, labelId })` | `resend.Inboxes.Labels.remove(inbox_id, label_id)` |
24
+ | List threads | `resend.inboxes.threads.list({ inboxId, ...params })` | `resend.Inboxes.Threads.list(inbox_id, params?)` |
25
+ | Search threads | `resend.inboxes.threads.search({ inboxId, ...params })` | `resend.Inboxes.Threads.search(inbox_id, params?)` |
26
+ | Get thread | `resend.inboxes.threads.get({ inboxId, threadId })` | `resend.Inboxes.Threads.get(inbox_id, thread_id)` |
27
+ | Update thread | `resend.inboxes.threads.update({ inboxId, threadId, ...params })` | `resend.Inboxes.Threads.update(params)`, `inbox_id` and `id` inside params |
28
+ | Delete thread | `resend.inboxes.threads.remove({ inboxId, threadId })` | `resend.Inboxes.Threads.remove(inbox_id, thread_id)` |
29
+ | List thread emails | `resend.inboxes.threads.emails.list({ inboxId, threadId, ...params })` | `resend.Inboxes.Threads.Emails.list(inbox_id, thread_id, params?)` |
30
+ | Get thread email | `resend.inboxes.threads.emails.get({ inboxId, threadId, emailId })` | `resend.Inboxes.Threads.Emails.get(inbox_id, thread_id, email_id)` |
31
+ | Reply to thread email | `resend.inboxes.threads.emails.reply({ inboxId, threadId, emailId, ...params })` | `resend.Inboxes.Threads.Emails.reply(params)`, `inbox_id`, `thread_id` and `email_id` inside params |
32
+ | Forward thread email | `resend.inboxes.threads.emails.forward({ inboxId, threadId, emailId, ...params })` | `resend.Inboxes.Threads.Emails.forward(params)`, `inbox_id`, `thread_id` and `email_id` inside params |
33
+ | List drafts | `resend.inboxes.drafts.list({ inboxId, ...params })` | `resend.Inboxes.Drafts.list(inbox_id, params?)` |
34
+ | Create draft | `resend.inboxes.drafts.create({ inboxId, ...params })` | `resend.Inboxes.Drafts.create(params)`, `inbox_id` inside params |
35
+ | Get draft | `resend.inboxes.drafts.get({ inboxId, draftId })` | `resend.Inboxes.Drafts.get(inbox_id, draft_id)` |
36
+ | Update draft | `resend.inboxes.drafts.update({ inboxId, draftId, ...params })` | `resend.Inboxes.Drafts.update(params)`, `inbox_id` and `id` inside params |
37
+ | Delete draft | `resend.inboxes.drafts.remove({ inboxId, draftId })` | `resend.Inboxes.Drafts.remove(inbox_id, draft_id)` |
38
+ | Send draft | `resend.inboxes.drafts.send({ inboxId, draftId })` | `resend.Inboxes.Drafts.send(inbox_id, draft_id)` |
39
+
40
+ Use `.remove()`, not `.delete()`, in the Node.js SDK.
41
+
42
+ ## Inboxes
43
+
44
+ ```typescript
45
+ // Create an inbox on a domain of your team
46
+ const { data: created, error } = await resend.inboxes.create({
47
+ emailAddress: 'support@acme.com',
48
+ name: 'Customer Support',
49
+ fromName: 'Ada from Support',
50
+ });
51
+ // created: { object: 'inbox', id }
52
+
53
+ // List inboxes, newest first
54
+ const { data: inboxes } = await resend.inboxes.list({ limit: 20 });
55
+ // inboxes.data[i]: { id, name, email_address, from_name, unread, last_received, created_at, updated_at }
56
+
57
+ // Get an inbox by ID or by email address
58
+ const { data: inbox } = await resend.inboxes.get('support@acme.com');
59
+ // inbox: { object, id, name, email_address, domain_id, receiving_address, from_name, unread, drafts, last_received, created_at, updated_at }
60
+
61
+ // Change the internal name or the name recipients see
62
+ const { data: updated } = await resend.inboxes.update('b3e2b2b6-3f0e-4c8e-9ad3-2f43a1e2c7f1', {
63
+ name: 'Support',
64
+ fromName: 'Acme Support',
65
+ });
66
+
67
+ // Delete an inbox
68
+ const { data: deleted } = await resend.inboxes.remove('b3e2b2b6-3f0e-4c8e-9ad3-2f43a1e2c7f1');
69
+ ```
70
+
71
+ **Key gotchas:**
72
+ - Create returns only `{ object, id }`. Call `get` for the other fields.
73
+ - Without `forwarding`, the domain must have receiving enabled, DKIM and SPF verified, and the inbound MX record verified or pending. With `forwarding: true`, the domain only needs DKIM and SPF, and Resend returns a `receiving_address` to forward mail to.
74
+ - Create returns 422 for a domain that does not meet these rules, 409 for an address already in use, 403 when the team is at the inbox limit of its plan, and 451 for a blocked account.
75
+ - `get` accepts the inbox ID or its email address, without case. Every other inbox endpoint accepts only the inbox ID.
76
+ - List items carry fewer fields than `get`.
77
+ - `fromName` is a plain name, not `Name <email>`. It cannot contain a colon, `<`, `>`, or line breaks. An empty string removes it.
78
+ - Update needs at least one of `name` or `fromName`.
79
+
80
+ ## Agent Settings
81
+
82
+ ```typescript
83
+ const inboxId = 'b3e2b2b6-3f0e-4c8e-9ad3-2f43a1e2c7f1';
84
+
85
+ const { data: agent } = await resend.inboxes.agent.get({ inboxId });
86
+ // agent: { object: 'inbox_agent', instructions, tone, actions }
87
+
88
+ const { data: updated } = await resend.inboxes.agent.update({
89
+ inboxId,
90
+ instructions: 'Answer refund questions yourself. Escalate legal threats.',
91
+ tone: 'concise_professional',
92
+ actions: ['draft_reply', 'add_labels'],
93
+ });
94
+ ```
95
+
96
+ **Key gotchas:**
97
+ - An inbox without an agent returns `instructions: null`, `tone: null` and `actions: []`. Update creates the agent when the inbox has none.
98
+ - Omitted fields keep their value. Send `null` to clear `instructions` or `tone`.
99
+ - `actions` replaces the whole set, without duplicates. Send `[]` to disable all actions. The values are `draft_reply`, `forward_thread`, `add_labels`, `assign_thread`, `mark_as_spam`, `archive_thread` and `delete_thread`.
100
+ - `instructions` is at most 4000 characters.
101
+ - `tone` is one of `concise_professional`, `concise_casual`, `expanded_professional` and `expanded_casual`.
102
+
103
+ ## Labels
104
+
105
+ ```typescript
106
+ const inboxId = 'b3e2b2b6-3f0e-4c8e-9ad3-2f43a1e2c7f1';
107
+
108
+ const { data: label } = await resend.inboxes.labels.create({
109
+ inboxId,
110
+ name: 'Urgent',
111
+ color: '#E93D82',
112
+ });
113
+ // label: { object: 'inbox_label', id }
114
+
115
+ const { data: labels } = await resend.inboxes.labels.list({ inboxId });
116
+ // labels.data[i]: { id, name, color, created_at }
117
+
118
+ await resend.inboxes.labels.update({
119
+ inboxId,
120
+ labelId: label.id,
121
+ name: 'Billing',
122
+ color: '#F76B15',
123
+ });
124
+
125
+ await resend.inboxes.labels.remove({ inboxId, labelId: label.id });
126
+ ```
127
+
128
+ **Key gotchas:**
129
+ - `color` is a `#RRGGBB` hex string. The API returns it in uppercase. Without `color`, the API picks a random color.
130
+ - An inbox has at most 100 labels. Names are unique per inbox, compared without case. A duplicate name or a full inbox returns 422.
131
+ - The list is not paginated. It returns every label, oldest first.
132
+ - To label a thread, call `threads.update` with `addLabelIds`. `removeLabelIds` takes it off the thread and keeps the label. Only `labels.remove` deletes it.
133
+ - Deleting a label removes it from every thread. It does not send `inbox.thread.labels.updated` for those threads.
134
+
135
+ ## Threads
136
+
137
+ ```typescript
138
+ const inboxId = 'b3e2b2b6-3f0e-4c8e-9ad3-2f43a1e2c7f1';
139
+ const threadId = '7c1f0a2e-5d3b-4e8a-9f61-2b8d4c6e1a90';
140
+ const labelId = '7f9c1d2e-4a6b-4c3d-8e15-9b0a7c6d5e34';
141
+
142
+ // Unread threads in the Inbox folder, most recently active first
143
+ const { data: threads } = await resend.inboxes.threads.list({
144
+ inboxId,
145
+ folders: ['inbox'],
146
+ read: false,
147
+ limit: 20,
148
+ });
149
+ // threads.data[i]: { id, subject, from, to, cc, bcc, labels, email_count, has_attachment, has_draft, read, received_at, folder }
150
+
151
+ // Find threads by text, sender, recipient, attachment or date
152
+ const { data: results } = await resend.inboxes.threads.search({
153
+ inboxId,
154
+ query: 'invoice -draft',
155
+ from: ['billing@example.com'],
156
+ hasAttachment: true,
157
+ startDate: '2026-09-01',
158
+ endDate: '2026-09-30',
159
+ });
160
+ // results.data[i]: the thread fields plus matched_email_id and highlights
161
+
162
+ const { data: thread } = await resend.inboxes.threads.get({ inboxId, threadId });
163
+ // thread: { object, id, subject, folder, labels, read }
164
+
165
+ // Mark read, move to a folder, add and remove labels
166
+ const { data: changed } = await resend.inboxes.threads.update({
167
+ inboxId,
168
+ threadId,
169
+ read: true,
170
+ folder: 'archive',
171
+ addLabelIds: [labelId],
172
+ });
173
+ await resend.inboxes.threads.update({ inboxId, threadId, removeLabelIds: [labelId] });
174
+
175
+ // Move the thread to trash
176
+ const { data: trashed } = await resend.inboxes.threads.remove({ inboxId, threadId });
177
+ // trashed: { object, id, deleted }
178
+ ```
179
+
180
+ **Key gotchas:**
181
+ - Folders are `inbox`, `archive`, `spam`, `sent` and `trash`. A thread is in exactly one folder. The API sets `sent` for threads with only outbound emails. You cannot set it.
182
+ - `folders` defaults to `['inbox']`, or to `['inbox', 'archive', 'sent']` when `labels` is set. `spam` and `trash` are only included when you name them.
183
+ - `after` and `before` take a thread ID, not a date. Pass only one of them. A cursor thread that is not in the selected folders returns 404.
184
+ - Search can be up to about a minute behind new emails. All filters must match. `query`, `from`, `to`, `cc`, `bcc`, `hasAttachment`, `startDate` and `endDate` must all match the same email in the thread. When you set any of them, that email must itself be in one of `folders`.
185
+ - In `query`, every word must match. Wrap words in double quotes for an exact phrase. Start a word with `-` to exclude it.
186
+ - A search result has `matched_email_id`, the email that matched, and `highlights`, the matched text with each match in `**`. The thread email endpoints accept `matched_email_id` as `emailId`.
187
+ - Update needs at least one of `read`, `folder`, `addLabelIds` or `removeLabelIds`. Each label array takes 1 to 10 IDs. A label ID cannot be in both arrays, or the request returns 422.
188
+ - `removeLabelIds` takes the label off the thread. The label itself stays on the inbox.
189
+ - Update applies `read`, `folder`, added labels, then removed labels. It is not atomic. A 404 for a label leaves the earlier changes applied.
190
+ - `remove` moves the thread to `trash` and deletes it after 30 days. To restore it, update `folder` to `inbox`, `archive` or `spam`.
191
+
192
+ ## Thread Emails
193
+
194
+ ```typescript
195
+ const inboxId = 'b3e2b2b6-3f0e-4c8e-9ad3-2f43a1e2c7f1';
196
+ const threadId = '7c1f0a2e-5d3b-4e8a-9f61-2b8d4c6e1a90';
197
+
198
+ // Emails in the thread, oldest first
199
+ const { data: emails } = await resend.inboxes.threads.emails.list({ inboxId, threadId });
200
+ const emailId = emails.data[emails.data.length - 1].id;
201
+
202
+ // The full email, body included
203
+ const { data: email } = await resend.inboxes.threads.emails.get({ inboxId, threadId, emailId });
204
+ // email: { id, direction, from, to, cc, bcc, reply_to, subject, message_id, html, text, attachments, read, received_at }
205
+
206
+ // Reply from the inbox address. The API sets `to` from the email you reply to.
207
+ const { data: reply } = await resend.inboxes.threads.emails.reply({
208
+ inboxId,
209
+ threadId,
210
+ emailId,
211
+ text: 'Refund issued for order 1041.',
212
+ headers: { 'X-Ticket-Id': '4821' },
213
+ attachments: [
214
+ { filename: 'receipt.txt', content: Buffer.from('Order 1041 refunded').toString('base64') },
215
+ ],
216
+ }, { idempotencyKey: `refund-reply/${emailId}` });
217
+ // reply: { id } (the sent email ID)
218
+
219
+ // Forward the email with its attachments
220
+ const { data: forwarded } = await resend.inboxes.threads.emails.forward({
221
+ inboxId,
222
+ threadId,
223
+ emailId,
224
+ to: ['delivered@resend.dev'],
225
+ text: 'Flagging this refund request for you.',
226
+ }, { idempotencyKey: `refund-forward/${emailId}` });
227
+ // forwarded: { id } (the sent email ID)
228
+ ```
229
+
230
+ **Key gotchas:**
231
+ - `threads.emails.list` returns the emails oldest first. Pass the last `id` as `after` for the next, newer page. A cursor that is not an email of the thread returns 404.
232
+ - The `emailId` comes from `threads.emails.list` or from `matched_email_id` in a search result, not from `resend.emails`.
233
+ - Reply sends right away, with no stored draft. For a received email, the reply goes to its `Reply-To` addresses, or to its sender. For an email the inbox sent, it goes to that email's `to` recipients. You cannot set `to` on a reply.
234
+ - With `replyAll: true`, a reply to a received email also copies the other `To` addresses and the `cc` of that email. A reply-all to an email the inbox sent goes to its Reply-To when that is not the inbox address, else to its `to`, and copies its `cc`. The inbox address is left out, and duplicates are removed.
235
+ - Reply needs `html` or `text` with more than whitespace. Without `subject`, the thread subject is used with a `Re:` prefix. Forward uses a `Fwd:` prefix.
236
+ - Forward needs `to`. It quotes the original email and sends its attachments with your `attachments`. Together they can have up to 10 files and 25 MB of `content`. An original attachment that was sent from a URL (`path`) cannot be forwarded, and the request returns 422.
237
+ - `attachments` and `headers` have the same shape as on `resend.emails.send()`. Resend sets `In-Reply-To`, `References` and `Reply-To`. Setting one of them in `headers`, in any letter case, returns 422. An empty header name, or a line break or null character in a name or value, also returns 422.
238
+ - An empty file, a blocked file type, or a `path` that is not an `http` or `https` URL, or that points to `localhost`, returns 422.
239
+ - Reply and forward return only the sent email ID.
240
+ - Reply and forward take an `idempotencyKey` option, as on `resend.emails.send()`. See [Idempotency Keys](#idempotency-keys).
241
+
242
+ ## Drafts
243
+
244
+ ```typescript
245
+ const inboxId = 'b3e2b2b6-3f0e-4c8e-9ad3-2f43a1e2c7f1';
246
+
247
+ // A draft that starts a new thread
248
+ const { data: draft } = await resend.inboxes.drafts.create({
249
+ inboxId,
250
+ to: ['delivered@resend.dev'],
251
+ subject: 'Refund for order 1041',
252
+ text: 'Refund issued for order 1041.',
253
+ attachments: [
254
+ {
255
+ filename: 'receipt.txt',
256
+ content: Buffer.from('Order 1041 refunded').toString('base64'),
257
+ contentType: 'text/plain',
258
+ },
259
+ ],
260
+ }, { idempotencyKey: 'refund-draft/order-1041' });
261
+ // draft: { object: 'inbox_draft', id }
262
+
263
+ const { data: drafts } = await resend.inboxes.drafts.list({ inboxId, limit: 20 });
264
+
265
+ const { data: saved } = await resend.inboxes.drafts.get({ inboxId, draftId: draft.id });
266
+ // saved: { object, id, type, to, cc, bcc, subject, html, text, thread_id, reply_to_email_id, email_id, created_at, updated_at, attachments }
267
+ // saved.attachments[i]: { id, filename, content_type, size }
268
+
269
+ // Replace the body and every attachment
270
+ await resend.inboxes.drafts.update({
271
+ inboxId,
272
+ draftId: draft.id,
273
+ html: '<p>Refund issued for order 1041.</p>',
274
+ text: 'Refund issued for order 1041.',
275
+ attachments: [
276
+ {
277
+ filename: 'invoice-1041.txt',
278
+ content: Buffer.from('Invoice 1041, refunded in full').toString('base64'),
279
+ contentType: 'text/plain',
280
+ },
281
+ ],
282
+ });
283
+
284
+ const { data: sent } = await resend.inboxes.drafts.send(
285
+ { inboxId, draftId: draft.id, headers: { 'X-Ticket-Id': '4821' } },
286
+ { idempotencyKey: `refund-draft-send/${draft.id}` },
287
+ );
288
+ // sent: { id } (the sent email ID)
289
+
290
+ // Discard a draft you do not want to send
291
+ const { data: other } = await resend.inboxes.drafts.create({ inboxId, subject: 'Notes' });
292
+ await resend.inboxes.drafts.update({ inboxId, draftId: other.id, attachments: [] });
293
+ await resend.inboxes.drafts.remove({ inboxId, draftId: other.id });
294
+ ```
295
+
296
+ **Key gotchas:**
297
+ - For a reply draft, pass `threadId` and `replyToEmailId` together. Without `to`, the API addresses it like a reply. Send `to: []` to leave it empty.
298
+ - Each email can have one unsent reply draft. Creating another returns 200 with the ID of the existing draft, not 201. That request ignores every other field except `attachments`, which replaces the attachments of the existing draft.
299
+ - A draft needs at least one non-empty `to`, `cc`, `bcc`, `subject`, `text`, `html` or `attachments`. `to`, `cc` and `bcc` together have at most 50 recipients.
300
+ - The draft stores its attachments, so each one needs `content` (base64), `filename` and `contentType`. A `path` or `contentId` returns 422. The files on a draft can total 25 MB, with no limit on the count. An empty file or a blocked file type, such as `.exe`, returns 422.
301
+ - An update with `attachments` replaces every attachment on the draft. Send `[]` to remove them all. Omit the field to keep them.
302
+ - An update that sets `text` or `html` replaces the whole body. The part you omit becomes `null`, so send both to keep both.
303
+ - Send needs at least one `to` recipient, a non-empty `subject`, and `html` or `text`, or it returns 422. A reply draft created without `subject` has an empty subject with no `Re:` prefix, so set one before you send it. Update, remove or send on a draft that was already sent returns 409.
304
+ - `drafts.list` returns only unsent drafts, most recently updated first.
305
+ - `drafts.send` takes `headers`, an object of string values, as on `resend.emails.send()`. Create and update do not take headers. The header rules of reply and forward apply.
306
+ - Create and send take an `idempotencyKey` option. See [Idempotency Keys](#idempotency-keys).
307
+
308
+ ## Idempotency Keys
309
+
310
+ Create draft, send draft, reply and forward accept an idempotency key, the same as `resend.emails.send()`. Pass it in the options argument: `{ idempotencyKey }` in Node.js, `{"idempotency_key": ...}` in Python. Use it when you retry these calls, so a retry does not create a second draft or send a second email.
311
+
312
+ | Key Facts | |
313
+ |-----------|---|
314
+ | **Operations** | `drafts.create`, `drafts.send`, `threads.emails.reply`, `threads.emails.forward`. No other inbox operation takes it |
315
+ | **Format** | `<event-type>/<entity-id>` (e.g., `refund-reply/<email-id>`) |
316
+ | **Length** | 1 to 256 characters |
317
+ | **Expiration** | 24 hours |
318
+ | **Same key + same payload** | Returns the first successful (2xx) response without a new draft or email. The response has the `idempotent-replayed: true` header |
319
+ | **Failed first request** | Not stored. Retry it with the same key |
320
+ | **Same key + different payload** | Returns 409 `invalid_idempotent_request` |
321
+ | **Same key while the first request runs** | Returns 409 `concurrent_idempotent_requests` |
322
+
323
+ ## Webhook Events
324
+
325
+ Inboxes send `inbox.*` events. See the event list in [webhooks.md](webhooks.md#other-events).
326
+
327
+ - Each payload `data` has `source` (`api`, `dashboard`, `agent` or `system`) and `inbox_id`, plus `thread_id`, `email_id` or `draft_id` where they apply.
328
+ - Email and draft payloads carry the object without `html` or `text`. Call `threads.emails.get()` or `drafts.get()` for the body.
329
+ - The `draft` object in `inbox.draft.*` payloads lists `attachments` as `{ id, filename, content_type, size }`, without the file content.
330
+ - `inbox.deleted` carries only `inbox_id`. `inbox.draft.deleted` has no `draft` object.
331
+ - `inbox.thread.labels.updated` carries one label, in `added` or `removed`.
332
+ - Sending a draft sends both `inbox.draft.sent` and `inbox.email.sent`, in no fixed order.
333
+
334
+ ## Common Mistakes
335
+
336
+ | Mistake | Fix |
337
+ |---------|-----|
338
+ | Using an email address on `update`, `remove` or a sub-resource | Only `inboxes.get` accepts an address. Use the inbox ID everywhere else |
339
+ | Reading fields from the create response | Create inbox, label and draft return only `{ object, id }`. Call `get` |
340
+ | Setting `Reply-To` in `headers` on a reply, forward or draft send | Resend sets `In-Reply-To`, `References` and `Reply-To`. Leave them out of `headers` |
341
+ | Passing `to` on a reply | Reply sets `to` from the email you reply to. Use `forward` to send to someone new |
342
+ | Using an ID from `resend.emails.list()` as `emailId` | Use the ID from `threads.emails.list` or `matched_email_id` from a search |
343
+ | Expecting `threads.remove` to delete at once | It moves the thread to `trash` for 30 days. Update `folder` to restore it |
344
+ | Setting `folder: 'sent'` | `sent` is set by the API. Use `inbox`, `archive`, `spam` or `trash` |
345
+ | Using a named color like `'red'` | Use a `#RRGGBB` hex string |
346
+ | Passing a `path` attachment to a draft | Drafts store their files. Send `content`, `filename` and `contentType` |
347
+ | Sending `attachments` on a draft update to add one file | It replaces every attachment. Send the full list |
348
+ | Updating only `html` on a draft that has `text` | The omitted body part becomes `null`. Send both |
349
+ | Expecting a new email to show in search at once | Search can be up to about a minute behind. Use `threads.list` for the newest threads |
@@ -68,6 +68,15 @@ The `email.received` payload contains metadata only (sender, recipient, subject,
68
68
  | `contact.topics.updated` | Contact's topic subscriptions change |
69
69
  | `suppression.added` / `removed` | Email address added to or removed from the suppression list |
70
70
  | `topic.created` / `updated` / `deleted` | Topic created, updated, or deleted |
71
+ | `inbox.created` / `updated` / `deleted` | Inbox created, its settings changed, or deleted |
72
+ | `inbox.thread.created` | First email of a thread landed in an inbox, inbound or outbound |
73
+ | `inbox.email.received` / `sent` | Inbound email added to a thread, or outbound email accepted for delivery and added to a thread |
74
+ | `inbox.thread.folder.updated` | Thread moved between folders |
75
+ | `inbox.thread.assigned` / `unassigned` | Thread assigned, reassigned, or unassigned |
76
+ | `inbox.thread.labels.updated` | Label applied to or removed from a thread |
77
+ | `inbox.draft.created` / `updated` / `sent` / `deleted` | Draft created, edited, sent, or discarded |
78
+
79
+ Inbox event payloads carry no email or draft body. See [inboxes.md](inboxes.md#webhook-events).
71
80
 
72
81
  ## Setup
73
82
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vybekiit",
3
- "version": "0.7.33",
3
+ "version": "0.7.34",
4
4
  "description": "Choose your services, sign in, create a VybeKiit app, and open its verified local welcome page.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -36,13 +36,13 @@
36
36
  "typescript": "5.7.2",
37
37
  "vitest": "3.2.6",
38
38
  "@effect/vitest": "0.29.0",
39
- "@vybekiit/db": "0.7.33",
40
- "@vybekiit/deploy": "0.7.33",
41
- "@vybekiit/agent-kit": "0.7.33",
42
- "@vybekiit/core": "0.7.33",
43
- "@vybekiit/agent-mcp": "0.7.33",
44
- "@vybekiit/report-mode": "0.7.33",
45
- "@vybekiit/payments": "0.7.33"
39
+ "@vybekiit/agent-mcp": "0.7.34",
40
+ "@vybekiit/deploy": "0.7.34",
41
+ "@vybekiit/core": "0.7.34",
42
+ "@vybekiit/db": "0.7.34",
43
+ "@vybekiit/agent-kit": "0.7.34",
44
+ "@vybekiit/payments": "0.7.34",
45
+ "@vybekiit/report-mode": "0.7.34"
46
46
  },
47
47
  "scripts": {
48
48
  "build": "tsup && node scripts/bundleGlobalSkills.mjs",