API Authentication
API Authentication
Section titled “API Authentication”Learn how to authenticate with the mailiam API, manage API keys, and implement secure authentication in your applications.
Overview
Section titled “Overview”mailiam uses an adaptive authentication system that provides the right level of security for each use case. Unlike traditional APIs that require keys for everything, mailiam intelligently adapts based on your needs.
Three-Tier Key System
Section titled “Three-Tier Key System”mailiam provides three types of API keys, each designed for specific scenarios:
1. Admin Keys (mlm_sk_admin_*)
Section titled “1. Admin Keys (mlm_sk_admin_*)”Full account access - Complete control over your mailiam account.
- ✅ CLI operations
- ✅ Domain management
- ✅ API key management
- ✅ Billing and settings
- 🔴 Critical security - Never expose client-side
2. Usage Keys (mlm_sk_usage_*)
Section titled “2. Usage Keys (mlm_sk_usage_*)”Limited operational access - Form submissions and email sending only.
- ✅ Form submissions
- ✅ Email sending
- ❌ Cannot manage domains
- ❌ Cannot create API keys
- 🟡 Moderate security - Safe in server environments only
3. Public Tokens (mlm_pk_*)
Section titled “3. Public Tokens (mlm_pk_*)”Domain-specific, client-side safe - Limited to one domain.
- ✅ Form submissions for scoped domain
- ✅ Safe for static sites
- ✅ Can be exposed in JavaScript
- ❌ Cannot access other domains
- 🟢 Safe for client-side - Domain-scoped protection
Quick Comparison
Section titled “Quick Comparison”| Feature | Admin Keys | Usage Keys | Public Tokens |
|---|---|---|---|
| Manage domains | ✅ | ❌ | ❌ |
| Send emails | ✅ | ✅ | ✅ (scoped) |
| Create API keys | ✅ | ❌ | ❌ |
| Client-side safe | ❌ | ❌ | ✅ |
| Rate limit | 1000/hr | 1000/hr | 100/hr |
Authentication Decision Flow
Section titled “Authentication Decision Flow”Need admin operations? → Admin Key (server-only) ↓ NoBuilding backend API? → Usage Key (server-only) ↓ NoStatic site, simple forms? → No key needed! (origin validation) ↓ NoStatic site, need JS features? → Public Token (client-safe)API Key Format
Section titled “API Key Format”Format Specification
Section titled “Format Specification”Admin Keys: mlm_sk_admin_{64_hex_characters}Usage Keys: mlm_sk_usage_{64_hex_characters}Public Keys: mlm_pk_{domain_hash}_{64_hex_characters}Examples
Section titled “Examples”# Admin Key (full access)mlm_sk_admin_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6...
# Usage Key (forms and email only)mlm_sk_usage_x9y8z7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0f9e8d7c6b5a4...
# Public Token (domain-scoped)mlm_pk_a7f8b3e1_j4k5l6m7n8o9p0q1r2s3t4u5v6w7x8y9z0a1b2c3d4e5f6g7... ^^^^^^^^^ Domain hash - identifies the scoped domainCreating API Keys
Section titled “Creating API Keys”Via CLI (Recommended)
Section titled “Via CLI (Recommended)”# Create admin key (default - full access)mailiam auth create-key --name "Production Admin"
# Create usage key (forms and email only)mailiam auth create-key \ --name "Vercel API Route" \ --type usage
# Create public token (domain-scoped, client-safe)mailiam auth create-key \ --name "Public Token for mysite.com" \ --type public \ --domain mysite.com
# List all keysmailiam auth list-keys
# List keys by typemailiam auth list-keys --type publicVia API
Section titled “Via API”# Create admin keycurl -X POST https://api.mailiam.dev/api-keys \ -H "Authorization: Bearer $MAILIAM_ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Production Admin Key", "keyType": "admin" }'
# Create usage keycurl -X POST https://api.mailiam.dev/api-keys \ -H "Authorization: Bearer $MAILIAM_ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Vercel API Routes", "keyType": "usage", "rateLimit": 1000 }'
# Create public token (domain-scoped)curl -X POST https://api.mailiam.dev/api-keys \ -H "Authorization: Bearer $MAILIAM_ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Public Token for mysite.com", "keyType": "public", "domainScope": "mysite.com" }'Response Example
Section titled “Response Example”{ "success": true, "apiKey": { "keyId": "key_abc123", "name": "Public Token for mysite.com", "keyType": "public", "domainScope": "mysite.com", "permissions": ["forms:send"], "rateLimit": 100, "key": "mlm_pk_a7f8b3e1_j4k5l6m7...", "createdAt": "2024-01-15T10:30:00Z" }, "message": "Public key created successfully. Save the key securely - it will not be shown again.", "securityNote": "This public key is safe for client-side use but is scoped to the specified domain only."}Via Dashboard
Section titled “Via Dashboard”- Log into mailiam dashboard at https://mailiam.dev
- Navigate to API Keys section
- Click Create New Key
- Select key type (Admin, Usage, or Public)
- For public tokens, select the domain
- Click Generate Key
- Copy and save the key immediately (shown only once!)
Authentication Methods
Section titled “Authentication Methods”Server-Side Authentication
Section titled “Server-Side Authentication”For backend applications, include the API key in the request header:
curl -X POST https://api.mailiam.dev/projects \ -H "Authorization: Bearer mlm_sk_live_abc123..." \ -H "Content-Type: application/json" \ -d '{"name": "My Project"}'Alternative header formats:
# X-Api-Key headercurl -H "X-Api-Key: mlm_sk_live_abc123..." \ https://api.mailiam.dev/projects
# mailiam-Api-Key headercurl -H "mailiam-Api-Key: mlm_sk_live_abc123..." \ https://api.mailiam.dev/projectsClient-Side Form Submissions
Section titled “Client-Side Form Submissions”For browser form submissions to verified domains, no API key is required:
<!-- Direct form submission (no API key needed) --><form action="https://api.mailiam.dev/yourdomain.com/contact" method="POST"> <input name="name" placeholder="Name" required> <input name="email" type="email" placeholder="Email" required> <textarea name="message" placeholder="Message" required></textarea> <button type="submit">Send</button></form>Client-Side with Public Token (Safe!)
Section titled “Client-Side with Public Token (Safe!)”Public tokens are designed for client-side use and are completely safe to expose:
// Safe for static sites! Token is domain-scopedconst PUBLIC_TOKEN = 'mlm_pk_a7f8b3e1_j4k5l6m7n8o9p0q1...';
const response = await fetch('https://api.mailiam.dev/v1/mysite.com/send', { method: 'POST', headers: { 'X-Public-Token': PUBLIC_TOKEN, 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'John Doe', email: 'john@example.com', message: 'Hello from my static site!' })});
if (response.ok) { console.log('Message sent successfully!');}Why it’s safe:
- ✅ Only works for the specified domain (
mysite.com) - ✅ Cannot access other domains or admin functions
- ✅ Limited to 100 requests/hour
- ✅ Can only submit forms, nothing else
Server-Side with Usage Key
Section titled “Server-Side with Usage Key”For API routes and backend services, use usage keys:
// Never expose this in client code!const USAGE_KEY = process.env.MAILIAM_USAGE_KEY;
const response = await fetch('https://api.mailiam.dev/v1/mysite.com/send', { method: 'POST', headers: { 'X-Api-Key': USAGE_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ name: req.body.name, email: req.body.email, message: req.body.message })});Admin Operations
Section titled “Admin Operations”For CLI and administrative tasks, use admin keys:
// Only use in trusted server environmentsconst ADMIN_KEY = process.env.MAILIAM_ADMIN_KEY;
// Create a new domainconst response = await fetch('https://api.mailiam.dev/domains', { method: 'POST', headers: { 'Authorization': `Bearer ${ADMIN_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ domain: 'newdomain.com' })});API Endpoints and Authentication
Section titled “API Endpoints and Authentication”Endpoints by Authentication Requirement
Section titled “Endpoints by Authentication Requirement”| Endpoint | Method | Admin Key | Usage Key | Public Token | No Auth |
|---|---|---|---|---|---|
| Form Submissions | |||||
/v1/{domain}/send | POST | ✅ | ✅ | ✅ (scoped) | ✅ (origin) |
/f/{formId} | POST | ✅ | ✅ | ❌ | ✅ |
/c/{collection}/{form} | POST | ✅ | ✅ | ❌ | ✅ |
| Domain Management | |||||
/domains | GET | ✅ | ❌ | ❌ | ❌ |
/domains | POST | ✅ | ❌ | ❌ | ❌ |
/domains/{domain} | PUT, DELETE | ✅ | ❌ | ❌ | ❌ |
| API Key Management | |||||
/api-keys | GET, POST | ✅ | ❌ | ❌ | ❌ |
/api-keys/{keyId} | DELETE | ✅ | ❌ | ❌ | ❌ |
| Projects & Collections | |||||
/projects | GET, POST | ✅ | ❌ | ❌ | ❌ |
/collections | GET, POST | ✅ | ❌ | ❌ | ❌ |
| Analytics | |||||
/analytics | GET | ✅ | ✅ | ❌ | ❌ |
| Admin Operations | |||||
/admin/* | ALL | ✅ | ❌ | ❌ | ❌ |
Understanding the Table
Section titled “Understanding the Table”- Admin Key: Full access to everything
- Usage Key: Limited to sending emails and forms
- Public Token: Only works for the scoped domain’s form submissions
- No Auth: Works with origin validation for browser requests
Quick Reference
Section titled “Quick Reference”Use Admin Keys for:
- CLI operations (
mailiam push,mailiam domains) - Creating/managing API keys
- Domain configuration
- Billing management
Use Usage Keys for:
- Vercel/Netlify API routes
- Backend services sending emails
- Programmatic form submissions
- Integration with your application
Use Public Tokens for:
- Static websites with JavaScript
- Client-side form enhancements
- Public-facing integrations
- When you need a key but can’t hide it
Use No Authentication for:
- Simple HTML forms
- Static sites without JavaScript
- Quick prototypes
- Forms that “just work”
API Key Management
Section titled “API Key Management”Creating API Keys
Section titled “Creating API Keys”# Via CLImailiam auth create-key --name "Production API" --permissions "forms,domains"
# Via APIcurl -X POST https://api.mailiam.dev/api-keys \ -H "Authorization: Bearer mlm_sk_live_existing_key..." \ -H "Content-Type: application/json" \ -d '{ "name": "Production API", "permissions": ["forms", "domains", "analytics"], "restrictions": { "ip_whitelist": ["203.0.113.0/24"], "rate_limit": 1000 } }'Key Permissions
Section titled “Key Permissions”Configure granular permissions for API keys:
{ "permissions": [ "forms.read", "forms.write", "domains.read", "domains.write", "collections.read", "collections.write", "analytics.read", "projects.read", "projects.write" ], "restrictions": { "ip_whitelist": ["192.168.1.0/24", "203.0.113.10"], "domain_restrictions": ["example.com", "api.example.com"], "rate_limit": 5000, "expires_at": "2024-12-31T23:59:59Z" }}Rotating API Keys
Section titled “Rotating API Keys”Regularly rotate API keys for security:
# Create new keymailiam auth create-key --name "Production API v2"
# Test new keyexport MAILIAM_API_KEY="mlm_sk_live_new_key..."mailiam test config
# Update applications with new key# Then revoke old keymailiam auth revoke-key "old_key_id"Security Best Practices
Section titled “Security Best Practices”1. Environment Variables
Section titled “1. Environment Variables”Store API keys as environment variables:
# Developmentexport MAILIAM_API_KEY="mlm_sk_test_abc123..."
# Productionexport MAILIAM_API_KEY="mlm_sk_live_xyz789..."2. Never Commit Keys
Section titled “2. Never Commit Keys”Add to .gitignore:
# Environment files.env.env.local.env.production
# Configuration files with secretsmailiam.prod.yamlconfig/production.yaml3. Use Restricted Keys
Section titled “3. Use Restricted Keys”Create keys with minimal required permissions:
# Key only for form submissionsmailiam auth create-key \ --name "Forms Only" \ --permissions "forms.write" \ --rate-limit 100
# Key only for reading analyticsmailiam auth create-key \ --name "Analytics Read" \ --permissions "analytics.read" \ --rate-limit 504. IP Restrictions
Section titled “4. IP Restrictions”Limit API key usage to specific IP addresses:
{ "name": "Production API", "restrictions": { "ip_whitelist": [ "203.0.113.10", // Production server "192.168.1.0/24", // Internal network "2001:db8::/32" // IPv6 range ] }}5. Rate Limiting
Section titled “5. Rate Limiting”Set appropriate rate limits for each key:
{ "name": "High Volume API", "restrictions": { "rate_limit": 10000, // 10k requests per hour "burst_limit": 100 // 100 requests per minute }}Framework Integration
Section titled “Framework Integration”Next.js API Routes
Section titled “Next.js API Routes”export default async function handler(req, res) { if (req.method !== 'POST') { return res.status(405).json({ message: 'Method not allowed' }); }
try { const formData = new FormData(); Object.entries(req.body).forEach(([key, value]) => { formData.append(key, value); });
const response = await fetch('https://api.mailiam.dev/yourdomain.com/contact', { method: 'POST', headers: { 'X-Api-Key': process.env.MAILIAM_API_KEY }, body: formData });
if (response.ok) { res.status(200).json({ message: 'Message sent successfully' }); } else { const error = await response.json(); res.status(400).json({ error: error.message }); } } catch (error) { res.status(500).json({ error: 'Internal server error' }); }}Express.js Middleware
Section titled “Express.js Middleware”const express = require('express');const app = express();
// Middleware to add mailiam API keyapp.use('/api/mailiam', (req, res, next) => { req.headers['x-api-key'] = process.env.MAILIAM_API_KEY; next();});
// Contact form endpointapp.post('/api/contact', async (req, res) => { const formData = new FormData(); Object.entries(req.body).forEach(([key, value]) => { formData.append(key, value); });
try { const response = await fetch('https://api.mailiam.dev/yourdomain.com/contact', { method: 'POST', headers: { 'X-Api-Key': process.env.MAILIAM_API_KEY }, body: formData });
const result = await response.json(); res.json(result); } catch (error) { res.status(500).json({ error: error.message }); }});Laravel Integration
Section titled “Laravel Integration”'mailiam' => [ 'api_key' => env('MAILIAM_API_KEY'), 'base_url' => 'https://api.mailiam.dev',],
// app/Services/mailiamService.php<?php
namespace App\Services;
use Illuminate\Support\Facades\Http;
class mailiamService{ protected $apiKey; protected $baseUrl;
public function __construct() { $this->apiKey = config('services.mailiam.api_key'); $this->baseUrl = config('services.mailiam.base_url'); }
public function submitForm($domain, $form, $data) { $response = Http::withHeaders([ 'X-Api-Key' => $this->apiKey, ])->post("{$this->baseUrl}/{$domain}/{$form}", $data);
return $response->json(); }}Error Handling
Section titled “Error Handling”Authentication Errors
Section titled “Authentication Errors”Handle authentication errors gracefully:
const submitForm = async (formData) => { try { const response = await fetch('https://api.mailiam.dev/yourdomain.com/contact', { method: 'POST', headers: { 'X-Api-Key': process.env.MAILIAM_API_KEY }, body: formData });
if (response.status === 401) { throw new Error('Invalid API key'); }
if (response.status === 403) { throw new Error('Insufficient permissions'); }
if (response.status === 429) { throw new Error('Rate limit exceeded'); }
if (!response.ok) { throw new Error('Request failed'); }
return await response.json(); } catch (error) { console.error('Form submission error:', error); throw error; }};Common HTTP Status Codes
Section titled “Common HTTP Status Codes”| Code | Meaning | Resolution |
|---|---|---|
200 | Success | Request processed successfully |
400 | Bad Request | Check request format and required fields |
401 | Unauthorized | Verify API key is correct and active |
403 | Forbidden | Check API key permissions |
404 | Not Found | Verify endpoint URL and domain |
429 | Too Many Requests | Implement rate limiting and backoff |
500 | Server Error | Contact support if persistent |
Testing Authentication
Section titled “Testing Authentication”Test API Key Validity
Section titled “Test API Key Validity”# Test API keycurl -H "Authorization: Bearer mlm_sk_live_your_key..." \ https://api.mailiam.dev/projects
# Expected response for valid key:{ "projects": [...], "count": 5}
# Expected response for invalid key:{ "error": "Invalid API key", "code": "AUTH_INVALID_KEY"}Test Permissions
Section titled “Test Permissions”# Test specific permissioncurl -H "Authorization: Bearer mlm_sk_live_your_key..." \ https://api.mailiam.dev/analytics
# Test form submissioncurl -X POST https://api.mailiam.dev/yourdomain.com/contact \ -H "X-Api-Key: mlm_sk_live_your_key..." \ -F "name=Test User" \ -F "email=test@example.com" \ -F "message=Test message"Debug Authentication Issues
Section titled “Debug Authentication Issues”# Check API key statusmailiam auth status --debug
# Test API connectivitymailiam test config --check-api
# Validate permissionsmailiam auth permissions --key-id "key_abc123"Monitoring API Usage
Section titled “Monitoring API Usage”Usage Analytics
Section titled “Usage Analytics”Monitor API key usage:
# View API usagemailiam analytics api-usage --last-30d
# View by API keymailiam analytics api-usage --key "mlm_sk_live_abc123" --last-7d
# Export usage datamailiam analytics export --type api-usage --format csvRate Limit Monitoring
Section titled “Rate Limit Monitoring”Track rate limit usage:
# Check current rate limitscurl -H "Authorization: Bearer mlm_sk_live_your_key..." \ https://api.mailiam.dev/rate-limits
# Response includes current usage{ "rate_limits": { "requests_per_hour": { "limit": 5000, "remaining": 4847, "reset_time": "2024-01-01T15:00:00Z" }, "requests_per_minute": { "limit": 100, "remaining": 92, "reset_time": "2024-01-01T14:31:00Z" } }}Need Help?
Section titled “Need Help?”Documentation Resources
Section titled “Documentation Resources”- API Endpoints Reference - Complete endpoint documentation
- Rate Limits - Detailed rate limiting information
- CLI Authentication - CLI-specific authentication
Support Channels
Section titled “Support Channels”- API Documentation: https://api.mailiam.dev/docs
- Support Email: api-support@mailiam.dev
- Discord Community: Real-time API help
- GitHub Issues: Report API bugs and issues
Common Questions
Section titled “Common Questions”Q: Can I use API keys in frontend JavaScript? A: Only for trusted environments. Use domain-based authentication for public websites.
Q: How do I rotate API keys without downtime? A: Create a new key, test it, update your applications, then revoke the old key.
Q: What happens if I exceed rate limits?
A: You’ll receive a 429 Too Many Requests response. Implement exponential backoff.
Q: Can I restrict API keys to specific domains? A: Yes, use domain restrictions when creating keys.
Proper API authentication ensures secure access to mailiam’s services while maintaining the flexibility needed for various application architectures.