SDK Overview
Inboxical provides official SDKs that wrap the REST API with type-safe, ergonomic methods. Choose the package that matches your test runner.
| Package | Use case |
|---|---|
@inboxical/sdk | Node.js — Jest, Vitest, Mocha, or any Node runtime |
@inboxical/playwright | Playwright e2e tests with auto-managed mailboxes |
@inboxical/cypress | Cypress e2e tests via cy.task() integration |
@inboxical/sdk
Section titled “@inboxical/sdk”The core Node.js client. All other SDKs use this under the hood.
Install
Section titled “Install”npm install @inboxical/sdkQuick start
Section titled “Quick start”import { Inboxical } from '@inboxical/sdk'
const client = new Inboxical({ apiKey: process.env.INBOXICAL_API_KEY!,})
// Create an inboxconst inbox = await client.createInbox({ name: 'signup-test' })
// Trigger your app to send an email...
// Wait for the message (long-poll, up to 30s)const message = await client.waitForMessage(inbox.id, { timeout: 30 })console.log(message.subject) // "Welcome to MyApp!"
// Extract a verification code from the email bodyconst code = client.extractCode(message)console.log(code) // "482910"
// Clean upawait client.deleteInbox(inbox.id)Configuration
Section titled “Configuration”const client = new Inboxical({ apiKey: 'ixk_live_...', // Required baseUrl: 'https://....', // Optional — default: https://api.inboxical.com timeout: 30_000, // Optional — request timeout in ms (default: 30000)})Methods
Section titled “Methods”Inboxes
Section titled “Inboxes”| Method | Description |
|---|---|
createInbox(options?) | Create a new test inbox. Options: { name?, domain? } |
listInboxes(options?) | List inboxes with pagination. Options: { page?, limit? } |
getInbox(inboxId) | Get a single inbox by ID |
deleteInbox(inboxId) | Delete an inbox and all its messages |
Messages
Section titled “Messages”| Method | Description |
|---|---|
getMessages(inboxId, options?) | List messages with pagination. Options: { page?, limit? } |
getLatestMessage(inboxId) | Get the most recent message in an inbox |
waitForMessage(inboxId, options?) | Long-poll until a message arrives. Options: { timeout?, since? } |
getMessage(messageId) | Get a single message by ID |
deleteMessage(messageId) | Delete a single message |
Helpers
Section titled “Helpers”| Method | Description |
|---|---|
extractCode(message, options?) | Extract an OTP/verification code from a message body |
extractCode()
Section titled “extractCode()”Searches the message body for common verification code patterns (4-8 digit numbers preceded by words like “code”, “otp”, “pin”). Returns the code string or null.
const message = await client.waitForMessage(inbox.id)
// Auto-detect common patternsconst code = client.extractCode(message)
// Or supply a custom regex with a capture groupconst code = client.extractCode(message, { pattern: /verification-code: ([A-Z0-9]{6})/i,})Error handling
Section titled “Error handling”import { InboxicalApiError, InboxicalNetworkError } from '@inboxical/sdk'
try { const message = await client.waitForMessage(inbox.id, { timeout: 10 })} catch (err) { if (err instanceof InboxicalApiError) { console.log(err.status) // 408 (timeout), 404, etc. console.log(err.code) // Machine-readable error code } if (err instanceof InboxicalNetworkError) { console.log(err.message) // "Request timed out after 15000ms" }}All types are exported from the package:
import type { Inbox, Message, InboxList, MessageList, InboxicalOptions, CreateInboxOptions, PaginationOptions, WaitForMessageOptions, ExtractCodeOptions,} from '@inboxical/sdk'@inboxical/playwright
Section titled “@inboxical/playwright”A high-level mailbox helper designed for Playwright tests. Manages inbox lifecycle automatically.
Install
Section titled “Install”npm install @inboxical/playwrightQuick start
Section titled “Quick start”import { test, expect } from '@playwright/test'import { InboxicalMailbox } from '@inboxical/playwright'
test('user receives verification email', async ({ page }) => { const mailbox = new InboxicalMailbox() const { email } = await mailbox.create({ name: 'verify-test' })
await page.goto('/signup') await page.fill('#email', email) await page.click('button[type=submit]')
const message = await mailbox.waitForMessage({ timeout: 30 }) expect(message.subject).toContain('Verify')
const code = await mailbox.extractCode() await page.fill('#code', code) await page.click('#verify')
await expect(page.locator('.success')).toBeVisible() await mailbox.cleanup()})Configuration
Section titled “Configuration”InboxicalMailbox reads INBOXICAL_API_KEY from the environment by default. You can override it:
const mailbox = new InboxicalMailbox({ apiKey: 'ixk_live_...', // Optional — defaults to INBOXICAL_API_KEY env var baseUrl: 'https://...', // Optional})Methods
Section titled “Methods”| Method | Description |
|---|---|
create(options?) | Create a new inbox. Returns { id, email }. Cleans up any previous inbox |
waitForMessage(options?) | Long-poll for a message. Options: { timeout?, since? } |
getMessages() | Get all messages in the current inbox |
getLatestMessage() | Get the latest message |
extractCode(options?) | Extract OTP from the last fetched message. Options: { pattern? } |
cleanup() | Delete the current inbox. Safe to call multiple times |
getClient() | Access the underlying Inboxical SDK client |
getInboxId() | Get the current inbox ID (or null) |
getEmail() | Get the current inbox email address (or null) |
Playwright fixture
Section titled “Playwright fixture”Use createMailboxFixture() for automatic cleanup after each test:
import { test as base } from '@playwright/test'import { InboxicalMailbox, createMailboxFixture } from '@inboxical/playwright'
export const test = base.extend<{ mailbox: InboxicalMailbox }>({ mailbox: createMailboxFixture(),})import { test } from './fixtures'import { expect } from '@playwright/test'
test('welcome email after signup', async ({ page, mailbox }) => { const { email } = await mailbox.create()
await page.goto('/register') await page.fill('[name=email]', email) await page.fill('[name=password]', 'test-password-123') await page.click('[type=submit]')
const message = await mailbox.waitForMessage({ timeout: 30 }) expect(message.subject).toBe('Welcome to MyApp!')
await mailbox.cleanup()})@inboxical/cypress
Section titled “@inboxical/cypress”Registers Cypress tasks that call the Inboxical API from the Node.js process (required because Cypress commands run in the browser and cannot make cross-origin API calls directly).
Install
Section titled “Install”npm install @inboxical/cypress1. Register the plugin in cypress.config.ts:
import { defineConfig } from 'cypress'import { setupInboxical } from '@inboxical/cypress'
export default defineConfig({ e2e: { setupNodeEvents(on, config) { setupInboxical(on, config, { apiKey: process.env.INBOXICAL_API_KEY, }) return config }, },})You can also set INBOXICAL_API_KEY in cypress.env.json instead of passing it in options.
Available tasks
Section titled “Available tasks”| Task | Arguments | Returns |
|---|---|---|
inboxicalCreateInbox | { name?, domain? } or null | { id, email } |
inboxicalGetInbox | inboxId (string) | Inbox object |
inboxicalDeleteInbox | inboxId (string) | null |
inboxicalGetMessages | inboxId (string) | Message[] |
inboxicalGetLatestMessage | inboxId (string) | Message object |
inboxicalWaitForMessage | { inboxId, timeout?, since? } | Message object |
inboxicalGetMessage | messageId (string) | Message object |
inboxicalDeleteMessage | messageId (string) | null |
inboxicalExtractCode | { message, pattern? } | string | null |
Full example
Section titled “Full example”describe('Signup email flow', () => { let inbox: { id: string; email: string }
beforeEach(() => { cy.task('inboxicalCreateInbox', { name: 'signup-test' }).then((result) => { inbox = result as { id: string; email: string } }) })
afterEach(() => { cy.task('inboxicalDeleteInbox', inbox.id) })
it('sends welcome email after signup', () => { cy.visit('/register') cy.get('[name=email]').type(inbox.email) cy.get('[name=password]').type('test-password-123') cy.get('[type=submit]').click()
cy.url().should('include', '/dashboard')
cy.task('inboxicalWaitForMessage', { inboxId: inbox.id, timeout: 30, }).then((message: any) => { expect(message.subject).to.equal('Welcome to MyApp!') }) })
it('extracts verification code from email', () => { cy.visit('/register') cy.get('[name=email]').type(inbox.email) cy.get('[name=password]').type('test-password-123') cy.get('[type=submit]').click()
cy.task('inboxicalWaitForMessage', { inboxId: inbox.id, timeout: 30, }).then((message: any) => { cy.task('inboxicalExtractCode', { message }).then((code) => { cy.get('#verification-code').type(code as string) cy.get('#verify-button').click() cy.contains('Email verified').should('be.visible') }) }) })})