Docs · SDKs
TypeScript SDK
A zero-dependency typed client for Node 20+.
The TypeScript client lives in the Mailroom repo under sdk/ (package @mailroom/sdk). It has no dependencies: it uses the global fetch and node:crypto, and needs Node 20 or newer.
import { Mailroom } from '@mailroom/sdk';
const mr = new Mailroom({ apiKey: process.env.MAILROOM_API_KEY!, baseUrl: 'https://mailroom.capumattu.com' });#Methods
| Call | Endpoint |
|---|---|
mr.inboxes.create({ username?, display_name?, client_id? }) | POST /v1/inboxes |
mr.inboxes.list() · get(id) · delete(id) | /v1/inboxes |
mr.inboxes.createTemporary({ ttlSeconds }) | POST /v1/inboxes with ttl_seconds |
mr.domains.create/list/get/verify/update/delete | /v1/domains |
mr.messages.send(inboxId, { to, subject, text?, html?, attachments? }, { idempotencyKey? }) | POST …/messages/send |
mr.messages.reply(inboxId, messageId, { text?, html?, reply_all? }) | POST …/reply |
mr.messages.list(inboxId, { labels?, is_read?, direction? }) | GET …/messages |
mr.messages.wait(inboxId, { timeout?, since?, from?, subject? }) | GET …/messages/wait |
mr.messages.waitForVerification(inboxId, { timeout?, since?, from? }) | GET …/verification |
mr.messages.get(id) · update(id, { add_labels?, remove_labels?, is_read? }) | /v1/messages/:id |
mr.threads.list(inboxId) · get(id) | /v1/…/threads |
mr.search(q, { inbox_id? }) | GET /v1/search |
mr.inboxes.update(id, { display_name?, metadata? }) | PATCH /v1/inboxes/:id |
mr.threads.update(id, { metadata?, add_labels?, remove_labels? }) | PATCH /v1/threads/:id |
mr.contacts.list({ q?, label?, metadata? }) · get(id) · byAddress(address) | /v1/contacts |
mr.contacts.update(id, { name?, notes?, metadata?, add_labels?, remove_labels? }) | PATCH /v1/contacts/:id |
mr.knowledge.list/create/get/update/delete | /v1/knowledge |
mr.knowledge.search(q, { inbox_id?, limit? }) | GET /v1/knowledge/search |
mr.messages.draftReply(id, { instructions? }) | POST /v1/messages/:id/draft-reply |
mr.webhooks.create/list/get/update/delete/test | /v1/webhooks |
#Contacts and knowledge
// Who is this? Name, notes, metadata and labels, created from mail.
const c = await mr.contacts.byAddress('priya.n@gmail.com');
console.log(c.notes, c.metadata.crm_id); // "Wholesale…" "hs_48213"
// Link it to your CRM and remember something. Metadata merges; null deletes a key.
await mr.contacts.update(c.id, {
notes: `${c.notes ?? ''}
Asked about order 1042 on 25 Sep.`,
metadata: { crm_id: 'hs_48213', plan: 'wholesale' },
add_labels: ['customer'],
});
// Find contacts by your own id.
const { data } = await mr.contacts.list({ metadata: { crm_id: 'hs_48213' } });// Workspace-wide (no inbox_id) or for one inbox.
await mr.knowledge.create({
title: 'Shipping times',
body: '- Germany: 1–2 working days (DHL)
- EU: 3–5 working days',
inbox_id: inbox.id,
});
// Ranked full-text search. With inbox_id, workspace-wide documents are included too.
const { data: hits } = await mr.knowledge.search('how long does shipping to France take', { inbox_id: inbox.id });
// [{ id, title: 'Shipping times', inbox_id, rank: 0.61, snippet: '…EU: 3–5 working days…' }]#Errors
Non-2xx responses throw MailroomError with status, code and message from the API’s error body.
import { MailroomError } from '@mailroom/sdk';
try {
await mr.messages.send(inbox.id, { to: 'x@example.com', subject: 'Hi', text: '…' });
} catch (e) {
if (e instanceof MailroomError && e.code === 'daily_send_limit_exceeded') {
// back off until 00:00 UTC
}
}#Webhook verification
verifyWebhook(signature, timestamp, rawBody, secret, { toleranceSeconds? }) returns a boolean. See Webhooks for a full Express example.