Documentation / Getting Started

Authentication

4 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
Prefix Type Behaviour
ob_live_ Live Emails are sent for real
ob_test_ Test (sandbox) Nothing is sent — use it to test your integration

Test keys (sandbox)

A test key goes through exactly the same API path as a live key — authentication, validation, field limits, idempotency, rate limiting, response shapes and webhooks — but no email ever leaves our servers.

Create one in the dashboard (API Keys → New key → Test) or via the API:

curl -X POST https://api.mailingapi.com/v1/api-keys \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Integration tests", "domain_id": "...", "permissions": ["send", "read"], "mode": "test"}'

How test keys differ:

  • Messages are marked "sandbox": true in every response and webhook payload.
  • The simulated result depends on the recipient:
Recipient Result Webhook
bounce@simulator.mailingapi.com bounced (hard bounce, error_code: "hard_bounce") message.bounced
an address on your suppression list rejected —
any other address delivered with smtp_response: "250 sandbox: not sent" message.delivered
  • The sender domain does not have to be verified yet, but the from address must still be from the key’s domain.
  • Sandbox messages don’t count towards your plan’s monthly or daily limits, the domain’s daily limit, the per-recipient limit, statistics or reputation. API rate limits (per second / per minute) still apply.
  • Test keys don’t count towards the plan’s API key limit.
  • A test key only sees sandbox messages in GET /v1/messages, and a live key only sees live ones.
  • Sandbox messages are deleted after 7 days.

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": {
    "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. Successful responses include X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix epoch seconds). When you exceed the limit, you’ll receive 429 Too Many Requests:

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded",
    "retry_after": 5
  }
}

Every 429 includes the standard Retry-After header (integer seconds) and the same value as retry_after in the body. Wait that many seconds before retrying; reading the Retry-After header is recommended. See API Overview → Rate limiting for all headers.

Rate limits per API key action:

Action Default limit
Send email 100/minute
Read endpoints 1000/minute
Management 100/minute

Next steps

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

Error handling →