Email API PHP Client

Simple, powerful email sending API with support for attachments and custom headers.

Quick Start

$curl = curl_init();
$data = [
    'from' => '[email protected]',
    'to' => '[email protected]',
    'subject' => 'Hello World',
    'html' => '<h1>Welcome!</h1>'
];

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.shoutbox.net/send',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS => json_encode($data),
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('SHOUTBOX_API_KEY'),
        'Content-Type: application/json'
    ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

if ($err) {
    echo "cURL Error #:" . $err;
} else {
    echo $response;
}

PHP Setup

Follow these steps to set up Shoutbox in your PHP application:

1. Configuration

Create a config.php file:

<?php
return [
    'shoutbox' => [
        'key' => getenv('SHOUTBOX_API_KEY'),
        'base_url' => 'https://api.shoutbox.net'
    ]
];

2. Environment Variable

Add to your .env file:

SHOUTBOX_API_KEY=key_XXXXXXXXX

3. Optional: Create API Client Class

<?php

class ShoutboxClient
{
    private $apiKey;
    private $baseUrl;

    public function __construct($apiKey, $baseUrl = 'https://api.shoutbox.net')
    {
        $this->apiKey = $apiKey;
        $this->baseUrl = $baseUrl;
    }

    public function sendRequest($endpoint, $data)
    {
        $curl = curl_init();
        
        curl_setopt_array($curl, [
            CURLOPT_URL => $this->baseUrl . $endpoint,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => [
                'Authorization: Bearer ' . $this->apiKey,
                'Content-Type: application/json'
            ],
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);
        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);

        if ($err) {
            throw new Exception("cURL Error: " . $err);
        }

        return [
            'status' => $statusCode,
            'body' => json_decode($response, true)
        ];
    }
}

Basic Request Structure

FieldTypeRequiredDescription
fromstringYesSender email address
tostringYesRecipient email address(es)
subjectstringYesEmail subject line
htmlstringYesHTML content of the email
namestringNoSender name
reply_tostringNoReply-to email address

Recipients

Multiple Recipients

$client = new ShoutboxClient(getenv('SHOUTBOX_API_KEY'));

$response = $client->sendRequest('/send', [
    'from' => '[email protected]',
    'to' => '[email protected],[email protected]',
    'subject' => 'Team Update',
    'html' => '<h1>Important Announcement</h1>'
]);

Named Recipients

$client = new ShoutboxClient(getenv('SHOUTBOX_API_KEY'));

$response = $client->sendRequest('/send', [
    'from' => '[email protected]',
    'to' => 'John Doe <[email protected]>,Jane Smith <[email protected]>',
    'subject' => 'Team Meeting',
    'html' => '<h1>Meeting Invitation</h1>'
]);

Reply-To Address

$client = new ShoutboxClient(getenv('SHOUTBOX_API_KEY'));

$response = $client->sendRequest('/send', [
    'from' => '[email protected]',
    'reply_to' => 'Support Team <[email protected]>',
    'to' => '[email protected]',
    'subject' => 'Support Ticket Update',
    'html' => '<h1>Your ticket has been updated</h1>'
]);

Attachments

Complete Example with Attachments

$attachments = [
    [
        'content' => base64_encode(file_get_contents('reports/january_report.pdf')),
        'filename' => 'january_report.pdf'
    ],
    [
        'content' => base64_encode(file_get_contents('reports/data.xlsx')),
        'filename' => 'data.xlsx'
    ]
];

$client = new ShoutboxClient(getenv('SHOUTBOX_API_KEY'));

$response = $client->sendRequest('/send', [
    'from' => '[email protected]',
    'name' => 'Reports Team',
    'to' => 'John Smith <[email protected]>',
    'subject' => 'Monthly Report - January 2024',
    'html' => '<h1>Monthly Report</h1><p>Please find your report attached.</p>',
    'attachments' => $attachments
]);

Background Processing for Large Attachments

function processLargeEmail($recipient, $reportPath) {
    // Set unlimited execution time for large files
    set_time_limit(0);
    
    try {
        $attachment = [
            'content' => base64_encode(file_get_contents($reportPath)),
            'filename' => basename($reportPath)
        ];

        $client = new ShoutboxClient(getenv('SHOUTBOX_API_KEY'));
        
        return $client->sendRequest('/send', [
            'from' => '[email protected]',
            'to' => $recipient,
            'subject' => 'Your Report',
            'html' => '<h1>Report Attached</h1>',
            'attachments' => [$attachment]
        ]);
    } catch (Exception $e) {
        error_log("Error sending email: " . $e->getMessage());
        throw $e;
    }
}

// Usage with background processing:
if (function_exists('fastcgi_finish_request')) {
    // Send response to client immediately
    http_response_code(202);
    header('Content-Type: application/json');
    echo json_encode(['message' => 'Processing started']);
    fastcgi_finish_request();
    
    // Continue processing in background
    processLargeEmail($recipient, $reportPath);
} else {
    // Regular synchronous processing
    processLargeEmail($recipient, $reportPath);
}

Custom Headers

Complete Example with Headers

$client = new ShoutboxClient(getenv('SHOUTBOX_API_KEY'));

$response = $client->sendRequest('/send', [
    'from' => '[email protected]',
    'name' => 'Newsletter Team',
    'to' => 'Subscriber <[email protected]>',
    'reply_to' => 'Newsletter Support <[email protected]>',
    'subject' => 'Your Weekly Newsletter',
    'html' => "<h1>This Week's Updates</h1><p>Latest news and updates...</p>",
    'headers' => [
        'List-Unsubscribe' => '<https://yourdomain.com/unsubscribe>',
        'List-Unsubscribe-Post' => 'List-Unsubscribe=One-Click',
        'X-Campaign-ID' => 'newsletter_2024_01',
        'X-Mailer' => 'ShoutboxAPI/1.0',
        'Precedence' => 'bulk',
        'X-Auto-Response-Suppress' => 'OOF, AutoReply'
    ]
]);

Error Handling

try {
    $client = new ShoutboxClient(getenv('SHOUTBOX_API_KEY'));
    $response = $client->sendRequest('/send', $data);

    if ($response['status'] !== 200) {
        error_log('Shoutbox API Error: ' . json_encode([
            'status' => $response['status'],
            'body' => $response['body']
        ]));

        throw new Exception('Failed to send email: ' . $response['status']);
    }
} catch (Exception $e) {
    error_log($e->getMessage());
    throw $e;
}

Security Best Practices

Here are some important security practices to follow when using our API:

Email Validation

function validateEmail($email) {
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        throw new InvalidArgumentException('Invalid email address');
    }
    return $email;
}

function validateRequest($data) {
    if (empty($data['to'])) {
        throw new InvalidArgumentException('Recipient email is required');
    }
    if (empty($data['subject']) || strlen($data['subject']) > 255) {
        throw new InvalidArgumentException('Subject is required and must be less than 255 characters');
    }
    if (empty($data['html'])) {
        throw new InvalidArgumentException('HTML content is required');
    }
    
    // Validate email addresses
    validateEmail($data['from']);
    foreach(explode(',', $data['to']) as $to) {
        // Extract email from "Name <email>" format
        if (preg_match('/<(.+)>/', $to, $matches)) {
            validateEmail($matches[1]);
        } else {
            validateEmail($to);
        }
    }
    
    return $data;
}

Rate Limiting

class RateLimiter {
    private $redis;
    private $maxRequests = 60;
    private $perSeconds = 60;

    public function __construct() {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);
    }

    public function checkLimit($key) {
        $current = $this->redis->get($key);
        if (!$current) {
            $this->redis->setex($key, $this->perSeconds, 1);
            return true;
        }
        
        if ($current >= $this->maxRequests) {
            return false;
        }
        
        $this->redis->incr($key);
        return true;
    }
}

// Usage:
$limiter = new RateLimiter();
if (!$limiter->checkLimit('api:' . $_SERVER['REMOTE_ADDR'])) {
    http_response_code(429);
    die(json_encode(['error' => 'Too many requests']));
}

Additional Security Measures

  1. Always use environment variables for API keys
  2. Implement background processing for large attachments
  3. Use HTTPS for all API calls
  4. Sanitize HTML content before sending
  5. Implement comprehensive logging
  6. Use secure file operations

Rate Limits

Our API implements rate limiting to ensure fair usage and system stability. The default rate limits are:

  • 60 requests per minute per API key
  • Maximum attachment size: 10MB
  • Maximum recipients per email: 50

Please contact support if you need higher limits for your use case.

Support

For additional support or questions, please contact our support team.