Installation & Setup
This guide covers everything you need to install and configure Inbound in your application, including SDK installation, environment configuration, and TypeScript setup.
SDK Installation
Install the Inbound SDK using your preferred package manager:
The Inbound SDK is published as inboundemail on npm. It includes TypeScript definitions and works with Node.js 18+ and all modern JavaScript frameworks. Using Yarn v2+? The SDK is compatible with all Yarn versions including Plug’n’Play mode. Bun users get native TypeScript support and faster installation times. pnpm’s efficient disk space usage makes it great for monorepos with multiple projects using Inbound.
Current SDK Version : 0.18.0Check the changelog for the latest features and updates.
Getting Your API Key
Sign up for Inbound
Visit inbound.new and create an account. You can sign up with:
Email and password
GitHub OAuth
Google OAuth
Create an API key
Once logged in, navigate to Settings > API Keys and click Create API Key . Give your API key a descriptive name like “Production API” or “Development Environment”.
Copy and store securely
Copy your API key immediately - you won’t be able to see it again! Never commit API keys to version control. Always use environment variables.
Environment Variables
Store your API key in environment variables for secure access:
.env
Next.js
Vercel
Docker
Create a .env file in your project root: INBOUND_API_KEY = your_api_key_here
Add .env to your .gitignore: .env
.env.local
.env.*.local
Next.js automatically loads .env.local for local development: INBOUND_API_KEY = your_api_key_here
For production, add environment variables in your hosting platform:
Vercel: Project Settings > Environment Variables
Netlify: Site Settings > Environment Variables
Railway: Project > Variables
Add environment variables in your Vercel project:
Go to your project settings
Navigate to Environment Variables
Add INBOUND_API_KEY with your API key
Select which environments to apply it to (Production, Preview, Development)
# Or use Vercel CLI
vercel env add INBOUND_API_KEY
Pass environment variables to your Docker container: ENV INBOUND_API_KEY=your_api_key_here
Or use docker-compose: version : '3.8'
services :
app :
environment :
- INBOUND_API_KEY=${INBOUND_API_KEY}
Then load from .env file: docker-compose --env-file .env up
TypeScript Configuration
The Inbound SDK is written in TypeScript and includes full type definitions. No additional @types packages needed!
Recommended tsconfig.json
{
"compilerOptions" : {
"target" : "ES2020" ,
"module" : "ESNext" ,
"lib" : [ "ES2020" ],
"moduleResolution" : "bundler" ,
"resolveJsonModule" : true ,
"strict" : true ,
"esModuleInterop" : true ,
"skipLibCheck" : true ,
"forceConsistentCasingInFileNames" : true
}
}
Type Imports
The SDK exports comprehensive types for all API operations:
import {
Inbound ,
type InboundWebhookPayload ,
type InboundEmail ,
type InboundEmailAddress ,
type InboundAttachment ,
isInboundWebhookPayload
} from 'inboundemail'
Use isInboundWebhookPayload() to validate webhook payloads with type narrowing in TypeScript.
Framework-Specific Setup
Next.js
Express
Fastify
Remix
Next.js 15 App Router Create a route handler for webhooks: app/api/webhooks/email/route.ts
import { NextRequest , NextResponse } from 'next/server'
import { Inbound , isInboundWebhookPayload } from 'inboundemail'
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! )
export async function POST ( request : NextRequest ) {
const payload = await request . json ()
if ( ! isInboundWebhookPayload ( payload )) {
return NextResponse . json ({ error: 'Invalid webhook' }, { status: 400 })
}
// Process email
console . log ( 'Email received:' , payload . email . subject )
return NextResponse . json ({ success: true })
}
Next.js Pages Router pages/api/webhooks/email.ts
import type { NextApiRequest , NextApiResponse } from 'next'
import { Inbound , isInboundWebhookPayload } from 'inboundemail'
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! )
export default async function handler (
req : NextApiRequest ,
res : NextApiResponse
) {
if ( req . method !== 'POST' ) {
return res . status ( 405 ). json ({ error: 'Method not allowed' })
}
const payload = req . body
if ( ! isInboundWebhookPayload ( payload )) {
return res . status ( 400 ). json ({ error: 'Invalid webhook' })
}
// Process email
console . log ( 'Email received:' , payload . email . subject )
return res . status ( 200 ). json ({ success: true })
}
Express.js import express from 'express'
import { Inbound , isInboundWebhookPayload } from 'inboundemail'
const app = express ()
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! )
app . use ( express . json ())
app . post ( '/webhooks/email' , async ( req , res ) => {
const payload = req . body
if ( ! isInboundWebhookPayload ( payload )) {
return res . status ( 400 ). json ({ error: 'Invalid webhook' })
}
// Process email
console . log ( 'Email received:' , payload . email . subject )
// Auto-reply example
await inbound . reply ( payload . email , {
from: 'support@yourdomain.com' ,
text: 'Thanks for your email!'
})
res . json ({ success: true })
})
app . listen ( 3000 , () => {
console . log ( 'Server running on port 3000' )
})
Fastify import Fastify from 'fastify'
import { Inbound , isInboundWebhookPayload } from 'inboundemail'
const fastify = Fastify ({ logger: true })
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! )
fastify . post ( '/webhooks/email' , async ( request , reply ) => {
const payload = request . body
if ( ! isInboundWebhookPayload ( payload )) {
return reply . code ( 400 ). send ({ error: 'Invalid webhook' })
}
// Process email
fastify . log . info ( `Email received: ${ payload . email . subject } ` )
return { success: true }
})
fastify . listen ({ port: 3000 }, ( err ) => {
if ( err ) throw err
console . log ( 'Server running on port 3000' )
})
Remix app/routes/webhooks.email.tsx
import { json } from '@remix-run/node'
import type { ActionFunctionArgs } from '@remix-run/node'
import { Inbound , isInboundWebhookPayload } from 'inboundemail'
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! )
export async function action ({ request } : ActionFunctionArgs ) {
if ( request . method !== 'POST' ) {
return json ({ error: 'Method not allowed' }, { status: 405 })
}
const payload = await request . json ()
if ( ! isInboundWebhookPayload ( payload )) {
return json ({ error: 'Invalid webhook' }, { status: 400 })
}
// Process email
console . log ( 'Email received:' , payload . email . subject )
return json ({ success: true })
}
Initializing the Client
Create an Inbound client instance to interact with the API:
import { Inbound } from 'inboundemail'
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! )
Client Configuration Options
The Inbound client accepts optional configuration:
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! , {
baseUrl: 'https://api.inbound.new' , // Custom API base URL
timeout: 30000 , // Request timeout in milliseconds (default: 30000)
})
Most users don’t need to configure these options. The defaults work for all production use cases.
Verification
Verify your installation is working:
import { Inbound } from 'inboundemail'
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! )
async function verify () {
try {
// List domains to verify API connection
const domains = await inbound . domains . list ()
console . log ( '✅ Inbound SDK connected successfully!' )
console . log ( `You have ${ domains . data . length } domain(s) configured` )
} catch ( error ) {
console . error ( '❌ Failed to connect:' , error )
}
}
verify ()
Run the verification script:
Troubleshooting
If you see Cannot find module 'inboundemail':
Verify the package is installed: npm list inboundemail
Delete node_modules and reinstall: rm -rf node_modules && npm install
Clear your build cache: rm -rf .next (Next.js) or equivalent
If TypeScript can’t find the types:
Ensure you’re using TypeScript 5.0+
Check your tsconfig.json includes "moduleResolution": "bundler" or "node"
Try restarting your TypeScript server in your editor
API authentication failed
If you get 401 Unauthorized errors:
Verify your API key is correct
Check the environment variable is loaded: console.log(process.env.INBOUND_API_KEY)
Ensure you’re not accidentally committing your .env file
Regenerate your API key if you suspect it’s compromised
Webhook not receiving requests
If your webhook endpoint isn’t receiving emails:
Verify your webhook URL is publicly accessible
Check your email address configuration: inbound.emailAddresses.list()
Ensure your endpoint returns a 200 status code
Test locally with bun run inbound-webhook-test hello@yourdomain.com
Check your domain’s DNS records are properly configured
Next Steps
Quickstart Guide Follow the quickstart to send your first email and receive webhooks
API Reference Explore all available SDK methods and API endpoints
Webhook Examples See real-world examples of webhook processing
Webhook Verification Learn how to verify webhooks and test locally