> ## Documentation Index
> Fetch the complete documentation index at: https://jetemail.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel

> Official JetEmail Laravel SDK for transactional email

# Laravel SDK

The **[jetemail-laravel](https://github.com/jetemail/jetemail-laravel)** package is the official Laravel SDK for JetEmail transactional email (MIT license).

Create a **transactional** API key in the dashboard: **Outbound** → **Keys** → Add API key. Use that key with the SDK.

## Installation

```bash theme={null}
composer require jetemail/jetemail-laravel
```

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:

```bash theme={null}
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`:

```php theme={null}
'mailers' => [
    'jetemail' => [
        'transport' => 'jetemail',
    ],
],
```

Set it as your default mailer in `.env`:

```
MAIL_MAILER=jetemail
```

Then use Laravel's standard Mail API:

```php theme={null}
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

```php theme={null}
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

```php theme={null}
$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

```php theme={null}
$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

```php theme={null}
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

```php theme={null}
$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)

```php theme={null}
$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

```php theme={null}
use JetEmail\Laravel\JetEmail;

$jetemail = app(JetEmail::class);
$jetemail->email->send(new SendEmailOptions(...));
```

### Without Laravel

```php theme={null}
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 customise 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()`:

```php theme={null}
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:

```php theme={null}
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-Signature` header
* **Timestamp freshness** via `X-Webhook-Timestamp` (default: 5-minute tolerance)

You can adjust the tolerance (in seconds):

```
JETEMAIL_WEBHOOK_TOLERANCE=300
```

## Error Handling

```php theme={null}
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
}
```

***

For the full source and additional examples, see the **[GitHub repository](https://github.com/jetemail/jetemail-laravel)**.
