Official TypeScript SDK for the Jasni Email API
npm install jasni-sdkOfficial TypeScript/JavaScript SDK for the Jasni Email API.
``bash`
npm install jasni-sdk
`typescript
import { Jasni } from 'jasni-sdk'
const jasni = new Jasni('jsk_your_api_key')
// List accounts
const { accounts } = await jasni.accounts.list()
console.log(accounts)
// Send an email
const result = await jasni.emails.send({
from: 'me@mail.jasni.ai',
to: 'recipient@example.com',
subject: 'Hello from Jasni!',
text: 'This email was sent using the Jasni SDK.',
})
console.log('Sent:', result.messageId)
`
`typescript`
const jasni = new Jasni('jsk_your_api_key', {
baseUrl: 'https://api.jasni.ai', // Optional: custom base URL
})
`typescript
// List all email accounts
const { accounts } = await jasni.accounts.list()
// Create a new email account
const { account } = await jasni.accounts.create({
username: 'myaccount', // Optional: auto-generated if not provided
name: 'My Account', // Optional: display name
})
// Update an account
await jasni.accounts.update({
email: 'myaccount@mail.jasni.ai',
name: 'New Display Name',
})
// Delete an email account
await jasni.accounts.delete('myaccount@mail.jasni.ai')
`
`typescript
// List emails
const { emails } = await jasni.emails.list({
account: 'me@mail.jasni.ai',
folder: 'INBOX', // Optional: default is INBOX
limit: 50, // Optional: default is 50, max 100
})
// Get a specific email
const { email } = await jasni.emails.get(123, {
account: 'me@mail.jasni.ai',
folder: 'INBOX',
})
// Delete an email
await jasni.emails.delete(123, {
account: 'me@mail.jasni.ai',
})
// Mark as read/unread
await jasni.emails.markAsRead(123, { account: 'me@mail.jasni.ai' })
await jasni.emails.markAsUnread(123, { account: 'me@mail.jasni.ai' })
// Send an email
const result = await jasni.emails.send({
from: 'me@mail.jasni.ai',
to: ['recipient@example.com'],
subject: 'Hello!',
text: 'Plain text body',
html: '
HTML body
', // Optional// Reply to an email
const reply = await jasni.emails.reply(123, {
account: 'me@mail.jasni.ai',
text: 'Thanks for your email!',
replyAll: false, // Optional: default false
includeOriginal: true, // Optional: default true
})
// Forward an email
const forward = await jasni.emails.forward(123, {
account: 'me@mail.jasni.ai',
to: ['forward@example.com'],
text: 'FYI - see below', // Optional message
})
// Get all attachments from an email
const { attachments } = await jasni.emails.getAttachments(123, {
account: 'me@mail.jasni.ai',
})
for (const att of attachments) {
console.log(att.filename, att.contentType, att.size)
// att.content is base64 encoded
}
// Get a specific attachment (by filename or index)
const { attachment } = await jasni.emails.getAttachment(123, {
account: 'me@mail.jasni.ai',
attachment: 'document.pdf', // or use index: 0
})
// Get raw email (RFC 822 format)
const { raw } = await jasni.emails.getRaw(123, {
account: 'me@mail.jasni.ai',
})
// Filter emails by labels
const { emails } = await jasni.emails.list({
account: 'me@mail.jasni.ai',
labels: ['Important', 'Work'], // Filter by label names
// OR
labelIds: ['label-id-1', 'label-id-2'], // Filter by label IDs
})
`
`typescript
// List email threads
const { threads, totalThreads } = await jasni.emails.listThreads({
account: 'me@mail.jasni.ai',
folder: 'INBOX', // Optional
limit: 100, // Optional
})
for (const thread of threads) {
console.log(${thread.subject} (${thread.messageCount} messages))
}
// Get all emails in a thread
const thread = await jasni.emails.getThread('
account: 'me@mail.jasni.ai',
})
console.log(Thread: ${thread.subject})Participants: ${thread.participants.map(p => p.address).join(', ')}
console.log()
for (const email of thread.emails) {
console.log(- ${email.from.address}: ${email.text})`
}
`typescript
// List drafts
const { drafts } = await jasni.drafts.list({
account: 'me@mail.jasni.ai',
limit: 50,
})
// Create a draft
const { uid } = await jasni.drafts.create({
account: 'me@mail.jasni.ai',
to: 'recipient@example.com',
subject: 'Draft subject',
text: 'Draft body',
})
// Update a draft
await jasni.drafts.update({
account: 'me@mail.jasni.ai',
uid: 123,
subject: 'Updated subject',
text: 'Updated body',
})
// Delete a draft
await jasni.drafts.delete({
account: 'me@mail.jasni.ai',
uid: 123,
})
// Get a specific draft
const { email } = await jasni.drafts.get(123, {
account: 'me@mail.jasni.ai',
})
// Send a draft (removes it from Drafts folder)
const result = await jasni.drafts.send({
account: 'me@mail.jasni.ai',
uid: 123,
})
console.log('Sent with message ID:', result.messageId)
`
`typescript
// List labels
const { labels } = await jasni.labels.list({
includeCount: true, // Optional: include email count per label
})
// Create a label
const { label } = await jasni.labels.create({
name: 'Important',
color: '#ff0000', // Optional: hex color
description: 'Important emails', // Optional
})
// Delete a label
await jasni.labels.delete('label-id')
// Get labels for an email
const { labels } = await jasni.emails.labels.list(123, {
account: 'me@mail.jasni.ai',
})
// Assign labels to an email
await jasni.emails.labels.assign(123, {
account: 'me@mail.jasni.ai',
labels: ['Important', 'Work'], // Create labels if they don't exist
// OR
labelIds: ['label-id-1', 'label-id-2'], // Use existing label IDs
agentName: 'my-agent', // Optional: for tracking
metadata: { reason: 'Auto-categorized' }, // Optional
})
// Remove labels from an email
await jasni.emails.labels.remove(123, {
account: 'me@mail.jasni.ai',
labelIds: ['label-id-1'],
})
`
`typescript
// List webhooks
const { webhooks } = await jasni.webhooks.list()
// Get a specific webhook by ID
const { webhook } = await jasni.webhooks.get('webhook-id')
console.log(webhook.url, webhook.events, webhook.active)
// Create a webhook
const { webhook } = await jasni.webhooks.create({
url: 'https://my-server.com/webhook',
events: ['email.received', 'email.sent'],
description: 'My webhook', // Optional
})
// Note: The secret is only returned on creation
// Update a webhook
await jasni.webhooks.update({
id: 'webhook-id',
url: 'https://new-url.com/webhook', // Optional
events: ['email.received'], // Optional
active: false, // Optional
description: 'Updated description', // Optional
})
// Delete a webhook
await jasni.webhooks.delete('webhook-id')
`
#### Webhook Events
- email.received - New email receivedemail.sent
- - Email sentemail.bounced
- - Email bouncedemail.spam
- - Email marked as spamemail.deleted
- - Email deleted
#### Verifying Webhook Signatures
Jasni signs all webhook payloads with HMAC-SHA256. Use the provided utilities to verify signatures:
`typescript
import { verifySignature, constructEvent } from 'jasni-sdk'
// Express.js example
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const payload = req.body
const signature = req.headers['x-jasni-signature'] as string
// Option 1: Manual verification
if (verifySignature(payload, signature, webhookSecret)) {
const event = JSON.parse(payload.toString())
handleEvent(event)
} else {
return res.status(401).send('Invalid signature')
}
// Option 2: Using constructEvent (verifies and parses)
try {
const event = constructEvent(payload, signature, webhookSecret)
if (event.event === 'email.received') {
console.log('New email from:', event.data.from)
}
res.status(200).send('OK')
} catch (err) {
res.status(401).send('Invalid signature')
}
})
`
For testing, you can generate signatures:
`typescript
import { generateSignature } from 'jasni-sdk'
const payload = JSON.stringify({ event: 'email.received', data: {} })
const signature = generateSignature(payload, 'whsec_test_secret')
`
`typescript
import { Jasni, JasniError, AuthenticationError, NotFoundError } from 'jasni-sdk'
try {
await jasni.emails.get(999, { account: 'me@mail.jasni.ai' })
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key')
} else if (error instanceof NotFoundError) {
console.error('Email not found')
} else if (error instanceof JasniError) {
console.error(API error: ${error.message} (${error.status}))`
}
}
This SDK is written in TypeScript and includes full type definitions.
`typescript``
import type {
// Core types
Email,
EmailPreview,
EmailAddress,
Account,
Label,
Webhook,
Draft,
ThreadPreview,
// Options types
SendEmailOptions,
ListEmailsOptions,
ListThreadsOptions,
CreateDraftOptions,
CreateWebhookOptions,
// Webhook payload types
WebhookPayload,
EmailReceivedPayload,
EmailSentPayload,
} from 'jasni-sdk'
MIT