PHP without our library

Simple, powerful email sending API with PHP integration

Email API PHP Client

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

Quick Start

$curl = curl_init();
$data = [
    'from' => 'sender@yourdomain.com',
    'to' => 'recipient@example.com',
    'subject' => 'Hello World',
    'html' => '<h1>Welcome!</h1>'
];

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.shoutbox.email/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.email'
    ]
];

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.email')
    {
        $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

Field Type Required Description
from string Yes Sender email address
to string Yes Recipient email address(es)
subject string Yes Email subject line
html string Yes HTML content of the email
name string No Sender name
reply_to string No Reply-to email address

Recipients

Multiple Recipients

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

$response = $client->sendRequest('/send', [
    'from' => 'no-reply@yourdomain.com',
    'to' => 'user1@example.com,user2@example.com',
    'subject' => 'Team Update',
    'html' => '<h1>Important Announcement</h1>'
]);

Named Recipients

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

$response = $client->sendRequest('/send', [
    'from' => 'no-reply@yourdomain.com',
    'to' => 'John Doe <john@example.com>,Jane Smith <jane@example.com>',
    'subject' => 'Team Meeting',
    'html' => '<h1>Meeting Invitation</h1>'
]);

Reply-To Address

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

$response = $client->sendRequest('/send', [
    'from' => 'no-reply@yourdomain.com',
    'reply_to' => 'Support Team <support@yourdomain.com>',
    'to' => 'customer@example.com',
    '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' => 'reports@yourdomain.com',
    'name' => 'Reports Team',
    'to' => 'John Smith <john@example.com>',
    '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' => 'reports@yourdomain.com',
            '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' => 'newsletter@yourdomain.com',
    'name' => 'Newsletter Team',
    'to' => 'Subscriber <subscriber@example.com>',
    'reply_to' => 'Newsletter Support <newsletter-support@yourdomain.com>',
    '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.