jetemail / jetemail-laravel
JetEmail for Laravel
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^7.0
- illuminate/http: ^10.0|^11.0|^12.0
- illuminate/mail: ^10.0|^11.0|^12.0
- illuminate/routing: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0
This package is not auto-updated.
Last update: 2026-04-02 12:21:05 UTC
README
Official Laravel SDK for the JetEmail transactional email service.
Installation
composer require jetemail/jetemail-laravel
Note: You need to create an account at jetemail.com to get a transactional API key before using this SDK.
The service provider and facade are auto-discovered by Laravel.
Configuration
Add your transactional API key to your .env file:
JETEMAIL_API_KEY=your-api-key
Optionally publish the config file:
php artisan vendor:publish --tag=jetemail-config
Laravel Mail Integration
Use JetEmail as a Laravel mail driver. Add the mailer to your config/mail.php:
'mailers' => [ 'jetemail' => [ 'transport' => 'jetemail', ], ],
Set it as your default mailer in .env:
MAIL_MAILER=jetemail
Then use Laravel's standard Mail API:
use Illuminate\Support\Facades\Mail; Mail::to('recipient@example.com')->send(new WelcomeEmail());
This works with all Laravel Mailables and Notifications out of the box.
Direct API Usage
Send a single email
use JetEmail\Laravel\Facades\JetEmail; use JetEmail\Laravel\Data\SendEmailOptions; $result = JetEmail::email->send(new SendEmailOptions( from: 'you@example.com', to: 'recipient@example.com', subject: 'Hello!', html: '<h1>Welcome</h1><p>Thanks for signing up.</p>', )); // $result['id'] - the message ID
Send with plain text
$result = JetEmail::email->send(new SendEmailOptions( from: 'you@example.com', to: 'recipient@example.com', subject: 'Hello!', text: 'Thanks for signing up.', ));
Multiple recipients, CC, BCC, Reply-To
$result = JetEmail::email->send(new SendEmailOptions( from: 'you@example.com', to: ['alice@example.com', 'bob@example.com'], subject: 'Team Update', html: '<p>Here is the latest update.</p>', cc: 'manager@example.com', bcc: ['logs@example.com'], replyTo: 'support@example.com', ));
Attachments
use JetEmail\Laravel\Data\Attachment; $result = JetEmail::email->send(new SendEmailOptions( from: 'you@example.com', to: 'recipient@example.com', subject: 'Invoice', html: '<p>Please find your invoice attached.</p>', attachments: [ Attachment::fromPath('/path/to/invoice.pdf'), Attachment::fromContent('Hello World', 'hello.txt'), ], ));
Custom headers
$result = JetEmail::email->send(new SendEmailOptions( from: 'you@example.com', to: 'recipient@example.com', subject: 'Tracked Email', html: '<p>Hello</p>', headers: [ 'X-Campaign-Id' => 'welcome-2024', ], ));
Batch send (up to 100 emails)
$result = JetEmail::batch->send([ new SendEmailOptions( from: 'you@example.com', to: 'alice@example.com', subject: 'Hello Alice', html: '<p>Hi Alice!</p>', ), new SendEmailOptions( from: 'you@example.com', to: 'bob@example.com', subject: 'Hello Bob', html: '<p>Hi Bob!</p>', ), ]); // $result['summary']['successful'] - number of emails sent // $result['results'] - per-email results
Without the facade
use JetEmail\Laravel\JetEmail; $jetemail = app(JetEmail::class); $jetemail->email->send(new SendEmailOptions(...));
Without Laravel
use JetEmail\Laravel\JetEmail; use JetEmail\Laravel\Data\SendEmailOptions; $jetemail = new JetEmail(apiKey: 'your-api-key'); $jetemail->email->send(new SendEmailOptions( from: 'you@example.com', to: 'recipient@example.com', subject: 'Hello!', html: '<p>Hello World</p>', ));
Webhooks
JetEmail can send webhook events to your application for email delivery events.
Setup
Add your webhook secret to .env:
JETEMAIL_WEBHOOK_SECRET=your-webhook-secret
The webhook endpoint is automatically registered at POST /jetemail/webhook. Point your JetEmail dashboard webhook URL to https://yourdomain.com/jetemail/webhook.
Configuration
You can customize the webhook route prefix and domain:
JETEMAIL_PATH=jetemail
JETEMAIL_DOMAIN=webhooks.yourdomain.com
Listening for events
Listen for webhook events in your EventServiceProvider or using Event::listen():
use JetEmail\Laravel\Events\Outbound\MessageDelivered; use JetEmail\Laravel\Events\Outbound\MessageBounced; use JetEmail\Laravel\Events\Outbound\MessageOpened; class EventServiceProvider extends ServiceProvider { protected $listen = [ MessageDelivered::class => [ HandleDeliveredEmail::class, ], MessageBounced::class => [ HandleBouncedEmail::class, ], ]; }
In your listener:
class HandleDeliveredEmail { public function handle(MessageDelivered $event): void { $payload = $event->payload; // $payload['id'] - event ID // $payload['type'] - 'outbound.delivered' // $payload['from'] - sender // $payload['to'] - recipient // $payload['subject'] - subject line // $payload['mx'] - receiving mail server } }
Available events
| Event Class | Webhook Type |
|---|---|
Events\Outbound\MessageQueued |
outbound.queued |
Events\Outbound\MessageDelivered |
outbound.delivered |
Events\Outbound\MessageDeferred |
outbound.deferred |
Events\Outbound\MessageBounced |
outbound.bounced |
Events\Outbound\MessageRejected |
outbound.rejected |
Events\Outbound\MessageSpam |
outbound.spam |
Events\Outbound\MessageVirus |
outbound.virus |
Events\Outbound\MessageDropped |
outbound.dropped |
Events\Outbound\MessageOpened |
outbound.opened |
Events\Outbound\MessageClicked |
outbound.clicked |
Events\Outbound\MessageComplaint |
outbound.complaint |
Signature verification
Webhook signatures are automatically verified when JETEMAIL_WEBHOOK_SECRET is set. The middleware validates:
- HMAC-SHA256 signature via the
X-Webhook-Signatureheader - Timestamp freshness via
X-Webhook-Timestamp(default: 5-minute tolerance)
You can adjust the tolerance (in seconds):
JETEMAIL_WEBHOOK_TOLERANCE=300
Error Handling
use JetEmail\Laravel\Exceptions\JetEmailException; try { JetEmail::email->send(new SendEmailOptions(...)); } catch (JetEmailException $e) { $e->getMessage(); // Error message $e->statusCode; // HTTP status code $e->response; // Full API error response }
License
MIT