Documentation / Getting Started

Authentication

2 min read

All API requests require authentication using an API key. This page explains how to create, use, and manage your API keys.

API Key Format

Outboxa API keys look like this:

ob_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
ob_test_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6

The prefix indicates the environment:

  • ob_live_ — Production keys, emails are sent for real
  • ob_test_ — Sandbox keys, emails are simulated (coming soon)

Using Your API Key

Include your API key in the Authorization header with the Bearer scheme:

curl -X POST https://api.mailingapi.com/v1/messages/send \
  -H "Authorization: Bearer ob_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"from": "...", "to": "...", "subject": "...", "html": "..."}'

Python

import requests

headers = {
    "Authorization": "Bearer ob_live_your_key_here",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api.mailingapi.com/v1/messages/send",
    headers=headers,
    json={...}
)

JavaScript

const response = await fetch('https://api.mailingapi.com/v1/messages/send', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ob_live_your_key_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({...})
});

API Key Permissions

Each API key has a permission level that controls what operations it can perform:

Permission Can do
send Send emails, analyze content
read Read messages, events, statistics
manage Manage domains, templates, webhooks, API keys
admin Full access including billing

When creating an API key, choose the minimum permissions needed. For example, if your backend only sends emails, use a send key.

Domain Binding

Each API key is bound to a specific domain. The from address in your emails must match the key’s domain:

Key domain: notifications.example.com
✓ from: "alerts@notifications.example.com"
✓ from: "no-reply@notifications.example.com"
✗ from: "hello@other-domain.com" — will fail

This prevents unauthorized sending from domains you don’t control.

Creating API Keys

Via Dashboard

  1. Go to Settings → API Keys
  2. Click Create new key
  3. Select the domain and permissions
  4. Copy and securely store the key

The full key is only shown once. Store it in your secrets manager or environment variables.

Via API

curl -X POST https://api.mailingapi.com/v1/api-keys \
  -H "Authorization: Bearer ob_live_admin_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Backend Production",
    "domain_id": "dom_123abc",
    "permissions": ["send", "read"]
  }'

Key Rotation

To rotate a key without downtime:

  1. Create a new key with the same permissions
  2. Update your application to use the new key
  3. Delete or revoke the old key

Or use our built-in rotation with grace period:

curl -X POST https://api.mailingapi.com/v1/api-keys/key_123/rotate \
  -H "Authorization: Bearer ob_live_admin_key" \
  -H "Content-Type: application/json" \
  -d '{"grace_period_minutes": 60}'

Both keys work during the grace period, giving you time to deploy updates.

Security Best Practices

Do

  • Store keys in environment variables or a secrets manager
  • Use separate keys for different environments (staging, production)
  • Use minimum required permissions
  • Rotate keys regularly (every 90 days recommended)
  • Monitor key usage in the dashboard

Don’t

  • Commit keys to version control
  • Share keys between applications
  • Use admin keys when send-only is sufficient
  • Log API keys in your application

Handling Authentication Errors

If authentication fails, you’ll receive a 401 Unauthorized response:

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing API key"
  }
}

Common causes:

  • Missing Authorization header
  • Invalid key format (not starting with ob_)
  • Revoked or deleted key
  • Key doesn’t have required permissions
  • from address doesn’t match key’s domain

Rate Limiting

API requests are rate limited per key. When you exceed the limit, you’ll receive 429 Too Many Requests:

{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests",
    "retry_after": 60
  }
}

Wait for retry_after seconds before retrying. Implement exponential backoff for production applications.

Rate limits vary by plan:

Plan Requests/minute
Free 60
Starter 300
Pro 1,000
Enterprise Custom

Next steps

Now that you understand authentication, learn how to handle errors gracefully.

Error handling →