Skip to main content

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

  1. Sign up or log in at inbound.new
  2. Navigate to SettingsAPI Keys
  3. Create a new API key or copy an existing one
  4. 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:
INBOUND_API_KEY=YOUR_API_KEY

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({ /* ... */ })
})

Bearer Token Format

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:
  1. Log in to your account
  2. Navigate to Settings > API Keys
  3. Generate a new API key
  4. 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

  1. Create a new API key in the dashboard
  2. Update your environment variables
  3. Deploy the changes
  4. 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:
PlanRate Limit
Free10 requests/second
Starter50 requests/second
Pro100 requests/second
EnterpriseCustom

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:
  1. Verify domain ownership in the dashboard
  2. Check DNS records are correctly configured
  3. 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/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

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

Build docs developers (and LLMs) love