Laravel
How to send emails with Unsent in Laravel
This guide shows how to install and use the official Unsent PHP SDK in a Laravel application.
Installation
Install the SDK via Composer. Run the following command in your Laravel project directory:
composer require souravsspace/unsentInitialize the Client
You can initialize the Unsent client in multiple ways in Laravel.
Option 1: Direct Initialization
<?php
use Souravsspace\Unsent\Unsent;
$client = new Unsent(env('UNSENT_API_KEY'));Option 2: Using a Service Provider
Create a service provider to register the Unsent client as a singleton:
php artisan make:provider UnsentServiceProvider<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Souravsspace\Unsent\Unsent;
class UnsentServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Unsent::class, function ($app) {
return new Unsent(config('services.unsent.api_key'));
});
}
}Add the provider to config/app.php:
'providers' => [
// ...
App\Providers\UnsentServiceProvider::class,
],And add the configuration to config/services.php:
'unsent' => [
'api_key' => env('UNSENT_API_KEY'),
],Send an Email
Now you can send emails. The SDK methods return a tuple [$data, $error]. You should always check if $error is present to handle any issues.
Here's an example in a controller:
<?php
namespace App\Http\Controllers;
use Souravsspace\Unsent\Unsent;
class EmailController extends Controller
{
public function send(Unsent $client)
{
[$data, $error] = $client->emails->send([
'to' => 'user@example.com',
'from' => 'no-reply@yourdomain.com',
'subject' => 'Welcome to Our App',
'html' => '<strong>Hello from Laravel!</strong>',
'headers' => ['X-Campaign' => 'welcome'],
]);
if ($error) {
return response()->json(['error' => $error['message']], 500);
}
return response()->json(['emailId' => $data['emailId']]);
}
}Or in a route:
use Illuminate\Support\Facades\Route;
use Souravsspace\Unsent\Unsent;
Route::get('/send-email', function (Unsent $client) {
[$data, $error] = $client->emails->send([
'to' => 'user@example.com',
'from' => 'no-reply@yourdomain.com',
'subject' => 'Hello from Laravel',
'html' => '<h1>It works!</h1>',
]);
if ($error) {
return response()->json(['error' => $error['message']], 500);
}
return response()->json($data);
});Note
Unsent forwards your custom headers to SES. Only the X-Unsent-Email-ID and References headers are managed automatically by Unsent.
Advanced Email Features
Attachments and Scheduling
You can send emails with attachments and schedule them for later delivery.
<?php
use DateTime;
[$data, $error] = $client->emails->send([
'to' => ['user1@example.com', 'user2@example.com'],
'from' => 'no-reply@yourdomain.com',
'subject' => 'Monthly Report',
'text' => 'Please see the attached report.',
'attachments' => [
[
'filename' => 'report.pdf',
'content' => base64_encode(file_get_contents(storage_path('reports/monthly.pdf'))),
],
],
'scheduledAt' => new DateTime('+1 hour'), // Schedule for 1 hour from now
]);Batch Send
Send multiple emails efficiently in a single request:
<?php
$emails = [
[
'to' => 'alice@example.com',
'from' => 'no-reply@yourdomain.com',
'subject' => 'Welcome Alice',
'html' => '<p>Welcome, Alice!</p>',
],
[
'to' => 'bob@example.com',
'from' => 'no-reply@yourdomain.com',
'subject' => 'Welcome Bob',
'html' => '<p>Welcome, Bob!</p>',
],
];
[$data, $error] = $client->emails->batch($emails);Idempotent Retries
Use idempotency keys to safely retry requests:
<?php
// For single email
$client->emails->send($email, ['idempotencyKey' => 'unique-key-' . $userId]);
// For batch emails
$client->emails->batch($emails, ['idempotencyKey' => 'batch-' . now()->timestamp]);Email Management
Get an Email
Fetch the status and details of a specific email:
<?php
[$email, $error] = $client->emails->get($emailId);
if ($email) {
echo "Status: {$email['status']}";
}Update Scheduled Email
Change the scheduled delivery time:
<?php
use DateTime;
[$data, $error] = $client->emails->update($emailId, [
'scheduledAt' => new DateTime('+2 hours'),
]);Cancel a Scheduled Email
<?php
[$data, $error] = $client->emails->cancel($emailId);List Emails
<?php
[$data, $error] = $client->emails->list([
'page' => 1,
'limit' => 50,
'startDate' => '2024-01-01T00:00:00Z',
'endDate' => '2024-12-31T23:59:59Z',
'domainId' => 'domain_123'
]);
if (!$error) {
foreach ($data['data'] as $email) {
echo "Email ID: {$email['id']}, Status: {$email['status']}\n";
}
}Get Email Events
<?php
[$data, $error] = $client->emails->getEvents($emailId, [
'page' => 1,
'limit' => 50
]);
if (!$error) {
foreach ($data as $event) {
echo "Event: {$event['type']} at {$event['timestamp']}\n";
}
}Contacts
Manage your contacts and organize them into contact books.
Create a Contact
<?php
[$data, $error] = $client->contacts->create($bookId, [
'email' => 'user@example.com',
'firstName' => 'Jane',
'properties' => ['plan' => 'pro'],
]);Get a Contact
<?php
[$contact, $error] = $client->contacts->get($bookId, $contactId);Update a Contact
<?php
[$data, $error] = $client->contacts->update($bookId, $contactId, [
'subscribed' => false,
'properties' => ['status' => 'inactive'],
]);Upsert a Contact
Create if doesn't exist, update if exists:
<?php
[$data, $error] = $client->contacts->upsert($bookId, $contactId, [
'email' => 'user@example.com',
'firstName' => 'Jane',
]);Delete a Contact
<?php
[$data, $error] = $client->contacts->delete($bookId, $contactId);Contact Books
Organize your contacts into groups.
List Contact Books
<?php
[$data, $error] = $client->contactBooks->list();
if (!$error) {
foreach ($data as $book) {
echo "Book: {$book['name']}\n";
}
}Create a Contact Book
<?php
[$data, $error] = $client->contactBooks->create([
'name' => 'Newsletter Subscribers',
'emoji' => '📧'
]);Get a Contact Book
<?php
[$data, $error] = $client->contactBooks->get($bookId);Update a Contact Book
<?php
[$data, $error] = $client->contactBooks->update($bookId, [
'name' => 'Updated Newsletter List',
]);Delete a Contact Book
<?php
[$data, $error] = $client->contactBooks->delete($bookId);Campaigns
Send emails to all contacts in a contact book.
Create a Campaign
<?php
[$data, $error] = $client->campaigns->create([
'name' => 'Welcome Series',
'from' => 'welcome@yourdomain.com',
'subject' => 'Welcome to our service!',
'html' => '<p>Thanks for joining us!</p>',
'contactBookId' => $bookId,
]);Get a Campaign
<?php
[$campaign, $error] = $client->campaigns->get($campaignId);Schedule a Campaign
<?php
[$data, $error] = $client->campaigns->schedule($campaignId, [
'scheduledAt' => '2024-12-01T10:00:00Z',
]);Pause/Resume a Campaign
<?php
// Pause
[$data, $error] = $client->campaigns->pause($campaignId);
// Resume
[$data, $error] = $client->campaigns->resume($campaignId);Domains
Manage your sending domains.
List Domains
<?php
[$domains, $error] = $client->domains->list();
if (!$error) {
foreach ($domains as $domain) {
echo "Domain: {$domain['name']}, Status: {$domain['status']}\n";
}
}Create a Domain
<?php
[$data, $error] = $client->domains->create([
'name' => 'yourdomain.com',
'region' => 'us-east-1',
]);Verify a Domain
<?php
[$data, $error] = $client->domains->verify($domainId);Get a Domain
<?php
[$domain, $error] = $client->domains->get($domainId);Delete a Domain
<?php
[$data, $error] = $client->domains->delete($domainId);Domain Analytics
<?php
[$data, $error] = $client->domains->getAnalytics($domainId, [
'days' => 30
]);Domain Stats
<?php
[$data, $error] = $client->domains->getStats($domainId);Templates
Create reusable email templates with variable placeholders.
List Templates
<?php
[$data, $error] = $client->templates->list();
if (!$error) {
foreach ($data as $template) {
echo "Template: {$template['name']}\n";
}
}Create a Template
<?php
[$data, $error] = $client->templates->create([
'name' => 'Welcome Email',
'subject' => 'Welcome to {{company}}!',
'html' => '<h1>Welcome, {{firstName}}!</h1>',
]);Get a Template
<?php
[$data, $error] = $client->templates->get($templateId);Update a Template
<?php
[$data, $error] = $client->templates->update($templateId, [
'subject' => 'Updated Subject Line',
]);Delete a Template
<?php
[$data, $error] = $client->templates->delete($templateId);Analytics
Get insights into your email performance.
Get Analytics Overview
<?php
[$data, $error] = $client->analytics->get();
if (!$error) {
echo "Sent: {$data['sent']}\n";
echo "Delivered: {$data['delivered']}\n";
echo "Bounced: {$data['bounced']}\n";
}Get Time Series Data
<?php
[$data, $error] = $client->analytics->getTimeSeries(['days' => 30]);
if (!$error) {
foreach ($data as $point) {
echo "Date: {$point['date']}, Sent: {$point['sent']}\n";
}
}Get Reputation Score
<?php
[$data, $error] = $client->analytics->getReputation();
if (!$error) {
echo "Reputation Score: {$data['score']}\n";
}API Keys
Manage API keys for your application.
List API Keys
<?php
[$data, $error] = $client->apiKeys->list();
if (!$error) {
foreach ($data as $key) {
echo "Key: {$key['name']}\n";
}
}Create an API Key
<?php
[$data, $error] = $client->apiKeys->create([
'name' => 'Production Key',
'permission' => 'SENDING'
]);
if (!$error) {
// Important: Save this token securely
echo "New API Key: {$data['token']}\n";
}Delete an API Key
<?php
[$data, $error] = $client->apiKeys->delete($keyId);Settings
Get your account settings.
<?php
[$data, $error] = $client->settings->get();
if (!$error) {
echo "Account: {$data['accountName']}\n";
}Suppressions
Manage your suppression list to prevent emails from being sent to certain addresses.
List Suppressions
<?php
[$data, $error] = $client->suppressions->list([
'page' => 1,
'limit' => 50
]);
if (!$error) {
foreach ($data['data'] as $suppression) {
echo "Email: {$suppression['email']}, Reason: {$suppression['reason']}\n";
}
}Add a Suppression
<?php
[$data, $error] = $client->suppressions->add([
'email' => 'user@example.com',
'reason' => 'MANUAL'
]);Delete a Suppression
<?php
[$data, $error] = $client->suppressions->delete('user@example.com');Webhooks
Future Feature
Webhooks are included in the SDK for reference as a future implementation. The webhook functionality is not yet fully operational in the API.
List Webhooks
<?php
[$data, $error] = $client->webhooks->list();Create a Webhook
<?php
[$data, $error] = $client->webhooks->create([
'url' => 'https://your-app.test/webhook',
'events' => ['email.sent', 'email.delivered']
]);Update a Webhook
<?php
[$data, $error] = $client->webhooks->update($webhookId, [
'url' => 'https://your-app.test/updated-webhook',
]);Delete a Webhook
<?php
[$data, $error] = $client->webhooks->delete($webhookId);System Operations
Check API health and get version information.
Health Check
<?php
[$data, $error] = $client->system->health();
if (!$error) {
echo "API Status: {$data['status']}\n";
echo "Uptime: {$data['uptime']} seconds\n";
}Get Version Information
<?php
[$data, $error] = $client->system->version();
if (!$error) {
echo "API Version: {$data['version']}\n";
echo "Environment: {$data['environment']}\n";
}Activity Feed
Retrieve your activity feed with email events and details.
<?php
[$data, $error] = $client->activity->get([
'page' => 1,
'limit' => 50
]);Events
List and filter email events.
List All Events
<?php
[$data, $error] = $client->events->list([
'page' => 1,
'limit' => 50,
'status' => 'DELIVERED',
'startDate' => '2024-01-01T00:00:00Z'
]);Teams
Manage team information.
List Teams
<?php
[$data, $error] = $client->teams->list();
if (!$error) {
foreach ($data as $team) {
echo "Team: {$team['name']}\n";
}
}Get Team Details
<?php
[$data, $error] = $client->teams->get($teamId);
if (!$error) {
echo "Team Name: {$data['name']}\n";
echo "Plan: {$data['plan']}\n";
}Metrics & Stats
Retrieve metrics and statistical data for your account.
Get Metrics
<?php
[$data, $error] = $client->metrics->get();Get Stats
<?php
[$data, $error] = $client->stats->get();Error Handling
The SDK supports two modes of error handling.
Raising Exceptions (Default)
By default, the SDK raises UnsentHTTPError exceptions for non-2xx responses:
<?php
use Souravsspace\Unsent\Unsent;
use Souravsspace\Unsent\UnsentHTTPError;
$client = new Unsent(env('UNSENT_API_KEY'));
try {
[$data, $_] = $client->emails->get($emailId);
return response()->json($data);
} catch (UnsentHTTPError $e) {
\Log::error("Unsent API Error: HTTP {$e->statusCode} - {$e->error['message']}");
return response()->json(['error' => $e->error['message']], $e->statusCode);
}Returning Error Tuples
If you prefer to handle errors as return values without exceptions:
<?php
// Pass false as the third argument to disable exceptions
$client = new Unsent(env('UNSENT_API_KEY'), null, false);
[$data, $error] = $client->emails->get($emailId);
if ($error) {
return response()->json(['error' => $error['message']], 500);
}
return response()->json($data);Using Laravel SMTP Driver
Alternatively, you can use Laravel's built-in SMTP driver instead of the SDK:
MAIL_MAILER=smtp
MAIL_HOST=smtp.unsent.dev
MAIL_PORT=587
MAIL_USERNAME=unsent
MAIL_PASSWORD=un_xxx
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="no-reply@yourdomain.com"
MAIL_FROM_NAME="${APP_NAME}"Then use Laravel's Mail facade:
<?php
use Illuminate\Support\Facades\Mail;
Mail::raw('Hello from Laravel!', function ($message) {
$message->to('user@example.com')
->subject('Test Email');
});