Overview
Inbound uses API key authentication to secure all API requests. Your API key is a secret credential that identifies your account and should be kept secure.
Getting Your API Key
Sign up or log in at inbound.new
Navigate to Settings → API Keys
Create a new API key or copy an existing one
Store it securely in your environment variables
Never commit API keys to version control or expose them in client-side code.
Setting Up Authentication
Using Environment Variables
Store your API key in environment variables:
.env
.env.local (Next.js)
Vercel
Docker
INBOUND_API_KEY = YOUR_API_KEY
INBOUND_API_KEY = YOUR_API_KEY
Add environment variable in:
Project Settings → Environment Variables Name: INBOUND_API_KEY
Value: YOUR_API_KEY
docker run -e INBOUND_API_KEY=YOUR_API_KEY myapp
SDK Authentication
Initialize the SDK with your API key:
import { Inbound } from 'inboundemail'
// Load from environment variable
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! )
// Or pass directly (not recommended for production)
const inbound = new Inbound ( 'YOUR_API_KEY' )
Direct API Authentication
Include your API key in the Authorization header:
const response = await fetch ( 'https://inbound.new/api/e2/emails' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . INBOUND_API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({ /* ... */ })
})
API keys must be sent as Bearer tokens in the Authorization header:
Authorization: Bearer YOUR_API_KEY
The Bearer prefix is required. Requests without it will return a 401 Unauthorized error.
Managing API Keys
Get your API key from the Inbound dashboard :
Log in to your account
Navigate to Settings > API Keys
Generate a new API key
Store it securely in your environment variables
API keys are tied to your account and have access to all resources (domains, emails, etc.) under that account. Keep them secure and rotate them regularly.
Security Best Practices
1. Never Expose API Keys
Never include API keys in:
Client-side JavaScript
Mobile app code
Public repositories
Browser requests
Frontend environment variables
// ❌ BAD - Exposed in client-side code
const inbound = new Inbound ( 'YOUR_API_KEY' )
// ✅ GOOD - Server-side only
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! )
2. Use Environment Variables
Always load API keys from environment variables:
// ✅ GOOD
const apiKey = process . env . INBOUND_API_KEY
if ( ! apiKey ) {
throw new Error ( 'INBOUND_API_KEY is not set' )
}
const inbound = new Inbound ( apiKey )
3. Separate Keys by Environment
Use different API keys for development, staging, and production:
// config.ts
export const config = {
apiKey: process . env . INBOUND_API_KEY ! ,
environment: process . env . NODE_ENV
}
// Verify correct key type
if ( config . environment === 'production' && config . apiKey . startsWith ( 'YOUR_TEST_API_KEY' )) {
throw new Error ( 'Cannot use test API key in production!' )
}
4. Rotate Keys Regularly
Create a new API key in the dashboard
Update your environment variables
Deploy the changes
Delete the old API key
Rotate API keys every 90 days or immediately if you suspect a key has been compromised.
5. Limit Key Permissions
When creating API keys, specify the minimum required permissions:
Read-only : For analytics and monitoring
Send-only : For transactional email services
Full access : For administrative tasks
6. Use Server-Side API Routes
For Next.js applications, always call Inbound from server-side routes:
// app/api/send-email/route.ts
import { Inbound } from 'inboundemail'
import { NextRequest , NextResponse } from 'next/server'
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! )
export async function POST ( request : NextRequest ) {
const { to , subject , html } = await request . json ()
const email = await inbound . emails . send ({
from: '[email protected] ' ,
to ,
subject ,
html
})
return NextResponse . json ({ success: true , emailId: email . id })
}
Rate Limiting
API requests are rate-limited based on your plan:
Plan Rate Limit Free 10 requests/second Starter 50 requests/second Pro 100 requests/second Enterprise Custom
Handling Rate Limits
try {
const email = await inbound . emails . send ({ /* ... */ })
} catch ( error ) {
if ( error . status === 429 ) {
// Rate limit exceeded
const retryAfter = error . headers . get ( 'Retry-After' )
console . log ( `Rate limited. Retry after ${ retryAfter } seconds` )
// Wait and retry
await new Promise ( resolve => setTimeout ( resolve , retryAfter * 1000 ))
// Retry the request
}
}
The Retry-After header indicates how many seconds to wait before retrying.
Authentication Errors
401 Unauthorized
Returned when the API key is missing, invalid, or expired:
{
"error" : "Unauthorized"
}
Common causes:
API key is missing from the Authorization header
API key format is incorrect
API key has been deleted or revoked
Bearer prefix is missing
Solution:
// Check your API key
const apiKey = process . env . INBOUND_API_KEY
console . log ( 'API Key:' , apiKey ? 'Set' : 'Missing' )
console . log ( 'Starts with:' , apiKey ?. substring ( 0 , 8 ))
// Verify authorization header format
const headers = {
'Authorization' : `Bearer ${ apiKey } ` , // Must include "Bearer "
'Content-Type' : 'application/json'
}
403 Forbidden
Returned when the API key lacks required permissions:
{
"error" : "You don't have permission to send from domain: example.com"
}
Common causes:
Domain is not verified
Domain belongs to another user
API key has restricted permissions
Solution:
Verify domain ownership in the dashboard
Check DNS records are correctly configured
Ensure API key has the required permissions
Testing Authentication
Verify your API key is working:
import { Inbound } from 'inboundemail'
async function testAuthentication () {
try {
const inbound = new Inbound ( process . env . INBOUND_API_KEY ! )
// Try to list domains
const domains = await inbound . domains . list ()
console . log ( '✅ Authentication successful' )
console . log ( `Found ${ domains . length } domains` )
} catch ( error ) {
if ( error . status === 401 ) {
console . error ( '❌ Authentication failed: Invalid API key' )
} else {
console . error ( '❌ Error:' , error . message )
}
}
}
testAuthentication ()
Environment Management
Local Development
# .env.local
INBOUND_API_KEY = YOUR_TEST_API_KEY
NODE_ENV = development
CI/CD Pipelines
Add secrets to your CI/CD environment:
GitHub Actions
GitLab CI
CircleCI
# .github/workflows/deploy.yml
name : Deploy
on :
push :
branches : [ main ]
jobs :
deploy :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v2
- name : Deploy
env :
INBOUND_API_KEY : ${{ secrets.INBOUND_API_KEY }}
run : npm run deploy
# .gitlab-ci.yml
deploy :
stage : deploy
script :
- npm run deploy
variables :
INBOUND_API_KEY : $INBOUND_API_KEY
only :
- main
# .circleci/config.yml
version : 2.1
jobs :
deploy :
docker :
- image : node:18
steps :
- checkout
- run :
name : Deploy
command : npm run deploy
environment :
INBOUND_API_KEY : ${INBOUND_API_KEY}
Next Steps
Error Handling Learn how to handle authentication and other errors
TypeScript SDK Explore the full SDK reference
Webhooks Configure webhooks for receiving emails
Rate Limits Understand rate limits and best practices