API ReferenceAuthentication

Authentication

Learn how to authenticate your API requests to Forma Mail.

Overview

Forma Mail API supports two authentication methods:

  1. API Keys (Recommended for production) - Long-lived credentials for server-to-server communication
  2. JWT Bearer Tokens - Short-lived tokens for dashboard and web applications

For most API integrations, you should use API Keys as they are designed for programmatic access.


API Key Authentication

How It Works

API Keys are long-lived credentials that allow your application to make authenticated requests to the Forma Mail API. Each request must include your API key in the Authorization header.

Creating an API Key

Step 1: Log in to Your Account

Visit the Forma Mail Dashboard and sign in to your account.

Step 2: Navigate to API Keys

  1. Click on Settings in the sidebar
  2. Select API Keys from the settings menu
  3. Click the Create API Key button

Step 3: Configure Your API Key

Fill in the following details:

  • Name: A descriptive name (e.g., “Production Server”, “Staging Environment”)
  • Description (optional): Additional notes about this key’s usage
  • Permissions: Select the permissions this key should have
    • emails:send - Send emails
    • emails:read - Read email logs
    • templates:read - Read templates
    • (Choose only the permissions you need)
  • Expiration (optional): Set an expiration date for added security
  • Rate Limit (optional): Limit requests per minute for this key

Step 4: Save Your API Key

Click Create API Key. You’ll see your new API key only once:

fm_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0

⚠️ Important: Copy and save this key immediately. For security reasons, we cannot show it to you again.

Using Your API Key

Include your API key in the Authorization header of every API request:

curl https://api.formamail.com/api/emails/send \
  -H "Authorization: Bearer fm_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0" \
  -H "Content-Type: application/json" \
  -d '{...}'

API Key Format

API keys follow this format:

fm_sk_{random_string}
  • fm_ - Forma Mail prefix
  • sk_ - Secret key identifier
  • {random_string} - Cryptographically secure random string

Example: fm_sk_a1b2c3d4e5f6g7h8i9j0...


Authentication Examples

Node.js / JavaScript

const axios = require('axios');
 
const API_KEY = 'fm_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0';
const API_URL = 'https://api.formamail.com/api';
 
// Configure axios with API key
const formaMailClient = axios.create({
  baseURL: API_URL,
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
});
 
// Send an email
async function sendEmail() {
  try {
    const response = await formaMailClient.post('/emails/send', {
      templateId: 'your-template-id',
      to: [{ email: 'user@example.com', name: 'John Doe' }],
      variables: {
        firstName: 'John',
        orderNumber: 'ORD-12345',
      },
    });
 
    console.log('Email sent:', response.data);
  } catch (error) {
    console.error('Error:', error.response.data);
  }
}
 
sendEmail();

Python

import requests
import json
 
API_KEY = 'fm_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0'
API_URL = 'https://api.formamail.com/api'
 
# Configure headers
headers = {
    'Authorization': f'Bearer {API_KEY}',
    'Content-Type': 'application/json'
}
 
# Send an email
def send_email():
    payload = {
        'templateId': 'your-template-id',
        'to': [{'email': 'user@example.com', 'name': 'John Doe'}],
        'variables': {
            'firstName': 'John',
            'orderNumber': 'ORD-12345'
        }
    }
 
    response = requests.post(
        f'{API_URL}/emails/send',
        headers=headers,
        data=json.dumps(payload)
    )
 
    if response.status_code == 201:
        print('Email sent:', response.json())
    else:
        print('Error:', response.json())
 
send_email()

PHP

<?php
 
$apiKey = 'fm_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0';
$apiUrl = 'https://api.formamail.com/api';
 
// Prepare request
$ch = curl_init($apiUrl . '/emails/send');
 
$payload = json_encode([
    'templateId' => 'your-template-id',
    'to' => [
        ['email' => 'user@example.com', 'name' => 'John Doe']
    ],
    'variables' => [
        'firstName' => 'John',
        'orderNumber' => 'ORD-12345'
    ]
]);
 
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json'
    ]
]);
 
// Execute request
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
 
if ($statusCode === 201) {
    echo 'Email sent: ' . $response;
} else {
    echo 'Error: ' . $response;
}

Ruby

require 'net/http'
require 'json'
 
API_KEY = 'fm_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0'
API_URL = 'https://api.formamail.com/api'
 
# Send an email
def send_email
  uri = URI("#{API_URL}/emails/send")
 
  request = Net::HTTP::Post.new(uri)
  request['Authorization'] = "Bearer #{API_KEY}"
  request['Content-Type'] = 'application/json'
 
  request.body = {
    templateId: 'your-template-id',
    to: [{ email: 'user@example.com', name: 'John Doe' }],
    variables: {
      firstName: 'John',
      orderNumber: 'ORD-12345'
    }
  }.to_json
 
  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
    http.request(request)
  end
 
  if response.code == '201'
    puts "Email sent: #{response.body}"
  else
    puts "Error: #{response.body}"
  end
end
 
send_email

cURL

curl -X POST https://api.formamail.com/api/emails/send \
  -H "Authorization: Bearer fm_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": "your-template-id",
    "to": [
      {
        "email": "user@example.com",
        "name": "John Doe"
      }
    ],
    "variables": {
      "firstName": "John",
      "orderNumber": "ORD-12345"
    }
  }'

API Key Management

Viewing API Keys

Navigate to Settings → API Keys to see all your API keys. You’ll see:

  • Key name and description
  • Creation date
  • Last used date
  • Expiration date (if set)
  • Permissions
  • Status (active/expired/revoked)

Rotating API Keys

For security, we recommend rotating your API keys periodically:

  1. Create a new API key with the same permissions
  2. Update your application to use the new key
  3. Test that the new key works
  4. Revoke the old API key

Revoking API Keys

If a key is compromised or no longer needed:

  1. Go to Settings → API Keys
  2. Find the key to revoke
  3. Click Revoke and confirm

Once revoked, the key immediately stops working. This action cannot be undone.


Security Best Practices

âś… DO

  • Store API keys securely - Use environment variables or secret managers
  • Create separate keys for different applications or services
  • Limit permissions - Only grant the permissions each key needs
  • Set expiration dates for added security
  • Rotate keys regularly - At least every 90 days
  • Revoke unused keys - Remove keys that are no longer needed
  • Monitor usage - Check the “Last Used” date regularly

❌ DON’T

  • Never commit API keys to version control (Git, SVN, etc.)
  • Don’t share API keys via email, Slack, or other communication channels
  • Don’t hardcode keys in your application source code
  • Don’t expose keys in client-side code (JavaScript, mobile apps)

Environment Variables

Store your API key in environment variables:

Linux/macOS (.env file):

FORMA_MAIL_API_KEY=fm_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
FORMA_MAIL_API_URL=https://api.formamail.com/api

Node.js (using dotenv):

require('dotenv').config();
 
const API_KEY = process.env.FORMA_MAIL_API_KEY;
const API_URL = process.env.FORMA_MAIL_API_URL;

Python:

import os
from dotenv import load_dotenv
 
load_dotenv()
 
API_KEY = os.getenv('FORMA_MAIL_API_KEY')
API_URL = os.getenv('FORMA_MAIL_API_URL')

Rate Limits

API keys are subject to rate limiting to ensure fair usage:

  • Default: 100 requests per minute
  • Burst: Up to 200 requests in a 10-second window
  • Custom limits: Contact us for high-volume requirements

Rate Limit Headers

Each API response includes rate limit headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
  • X-RateLimit-Limit - Total requests allowed per minute
  • X-RateLimit-Remaining - Requests remaining in current window
  • X-RateLimit-Reset - Unix timestamp when the limit resets

Handling Rate Limits

When you exceed the rate limit, you’ll receive a 429 Too Many Requests response:

{
  "statusCode": 429,
  "code": "RATE_LIMIT_EXCEEDED",
  "message": "Rate limit exceeded. Please try again in 30 seconds.",
  "timestamp": "2024-11-19T12:00:00.000Z",
  "path": "/api/emails/send"
}

Recommended approach:

async function sendWithRetry(payload, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await formaMailClient.post('/emails/send', payload);
      return response.data;
    } catch (error) {
      if (error.response?.status === 429) {
        const retryAfter = error.response.headers['retry-after'] || 30;
        console.log(`Rate limited. Retrying in ${retryAfter} seconds...`);
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      } else {
        throw error;
      }
    }
  }
  throw new Error('Max retries exceeded');
}

Error Responses

All authentication errors return a structured response:

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or missing API key",
  "timestamp": "2024-11-19T12:00:00.000Z",
  "path": "/api/emails/send"
}

Common Authentication Errors

StatusCodeMessageSolution
401UNAUTHORIZEDMissing Authorization headerInclude Authorization header
401INVALID_API_KEYInvalid API key formatCheck API key format
401API_KEY_NOT_FOUNDAPI key not foundVerify the key exists
401API_KEY_REVOKEDAPI key has been revokedCreate a new API key
401API_KEY_EXPIREDAPI key has expiredCreate a new API key
403FORBIDDENInsufficient permissionsCheck API key permissions

Testing Your API Key

Use this endpoint to verify your API key is working:

curl -X GET https://api.formamail.com/api/emails/usage/stats \
  -H "Authorization: Bearer YOUR_API_KEY"

Success response (200 OK):

{
  "email": {
    "used": 150,
    "limit": 1000,
    "remaining": 850,
    "percentUsed": 15
  },
  "attachment": {
    "used": 50,
    "limit": 500,
    "remaining": 450,
    "percentUsed": 10
  },
  "billingPeriod": "2024-11-01"
}

Next Steps


Back to API Reference