PHPackages                             graystackit/laravel-ahasend-api - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Mail &amp; Notifications](/categories/mail)
4. /
5. graystackit/laravel-ahasend-api

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

graystackit/laravel-ahasend-api
===============================

Laravel package for the Ahasend email API, powered by Saloon v4

00PHP

Since May 19Pushed 3w agoCompare

[ Source](https://github.com/GraystackIT/laravel-ahasend-api)[ Packagist](https://packagist.org/packages/graystackit/laravel-ahasend-api)[ RSS](/packages/graystackit-laravel-ahasend-api/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependenciesVersions (1)Used By (0)

laravel-ahasend-api
===================

[](#laravel-ahasend-api)

A production-ready Laravel package for the [Ahasend](https://ahasend.com) transactional email API, powered by **Saloon v4**.

Requirements
------------

[](#requirements)

- PHP 8.3+
- Laravel 11, 12, or 13
- Saloon 4.x
- Symfony Mailer 6.4 / 7.x (bundled with Laravel)

Installation
------------

[](#installation)

```
composer require graystackit/laravel-ahasend-api
```

The service provider is auto-discovered via Laravel's package discovery.

### Publish config

[](#publish-config)

```
php artisan vendor:publish --tag=ahasend-config
```

### Publish &amp; run migrations (optional — only needed for database storage driver)

[](#publish--run-migrations-optional--only-needed-for-database-storage-driver)

```
php artisan vendor:publish --tag=ahasend-migrations
php artisan migrate
```

Configuration
-------------

[](#configuration)

Set the following variables in your `.env` file:

```
AHASEND_API_KEY=your-api-key
AHASEND_ACCOUNT_ID=your-account-id
AHASEND_FROM_ADDRESS=hello@yourdomain.com
AHASEND_FROM_NAME="Your App"

# Optional
AHASEND_BASE_URL=https://api.ahasend.com/v2
AHASEND_WEBHOOK_SECRET=your-webhook-secret
AHASEND_STORE_LOGS=true
AHASEND_STORAGE_DRIVER=database   # "log" or "database"
AHASEND_RETRY_TIMES=3
AHASEND_RETRY_DELAY_MS=500
```

> **Note:** `AHASEND_ACCOUNT_ID` is required. You can find your account ID in the Ahasend dashboard.

Usage
-----

[](#usage)

### Dependency injection

[](#dependency-injection)

```
use GraystackIT\Ahasend\AhasendService;

class OrderController
{
    public function __construct(private readonly AhasendService $mailer) {}

    public function confirm(): void
    {
        $this->mailer->sendHtml(
            to:          [['email' => 'customer@example.com', 'name' => 'Jane']],
            subject:     'Order confirmed',
            htmlContent: 'Your order is confirmed!',
            textContent: 'Your order is confirmed!',
        );
    }
}
```

### Plain-text email

[](#plain-text-email)

```
$mailer->sendText(
    to:          [['email' => 'user@example.com']],
    subject:     'Hello',
    textContent: 'Hello from Ahasend!',
);
```

### HTML email

[](#html-email)

```
$mailer->sendHtml(
    to:          [['email' => 'user@example.com']],
    subject:     'Hello',
    htmlContent: 'Hello!',
    textContent: 'Hello!',   // optional plain-text fallback
);
```

### Email with attachments

[](#email-with-attachments)

```
$mailer->sendWithAttachments(
    to:          [['email' => 'user@example.com']],
    subject:     'Your invoice',
    attachments: [
        ['path' => storage_path('invoices/inv-001.pdf')],           // file path
        ['name' => 'data.csv', 'content' => $csvBase64, 'mime_type' => 'text/csv'], // raw
    ],
    htmlContent: 'Please find your invoice attached.',
);
```

### CC / BCC

[](#cc--bcc)

Pass `cc` and `bcc` arrays to any convenience method. When CC or BCC recipients are present the package automatically routes the request to the Ahasend conversational endpoint (`POST /messages/conversation`), which is the only endpoint that supports those fields:

```
$mailer->sendHtml(
    to:          [['email' => 'a@example.com']],
    subject:     'Test',
    htmlContent: 'Hi',
    cc:          [['email' => 'b@example.com']],
    bcc:         [['email' => 'c@example.com']],
);
```

### Low-level `EmailMessage`

[](#low-level-emailmessage)

```
use GraystackIT\Ahasend\Data\EmailMessage;

$message = new EmailMessage(
    fromEmail:   'from@example.com',
    fromName:    'Sender',
    to:          [['email' => 'to@example.com']],
    subject:     'Custom',
    htmlContent: 'Hello',
);

$ahasendMessageId = $mailer->send($message);
```

Webhook handling
----------------

[](#webhook-handling)

Register your endpoint URL in the Ahasend dashboard:

```
https://yourdomain.com/ahasend/webhook

```

The path is configurable via `AHASEND_WEBHOOK_PATH`. Incoming events fire Laravel events you can listen to:

Ahasend eventLaravel event`message.delivered``MailDelivered``message.opened``MailOpened``message.failed``MailFailed``message.bounced``MailBounced`### Listening to events

[](#listening-to-events)

```
// In EventServiceProvider or a listener class:
Event::listen(MailDelivered::class, function (MailDelivered $event): void {
    // $event->messageId, $event->recipient, $event->payload
});
```

Laravel Mail driver
-------------------

[](#laravel-mail-driver)

The package registers a native Laravel mail transport driver so you can send any standard Laravel `Mailable` through AhaSend without touching your existing Mailable code.

### 1. Configure the mailer

[](#1-configure-the-mailer)

Add an `ahasend` entry to the `mailers` array in `config/mail.php`:

```
// config/mail.php
'mailers' => [
    // ... other mailers ...

    'ahasend' => [
        'transport' => 'ahasend',
    ],
],
```

The transport reads API credentials and sender defaults from the `ahasend` config (i.e. the same `AHASEND_*` variables you already set).

To make AhaSend the **default** mailer, update your `.env`:

```
MAIL_MAILER=ahasend
```

### 2. Send a Mailable

[](#2-send-a-mailable)

```
use App\Mail\OrderShipped;
use Illuminate\Support\Facades\Mail;

// Uses the default mailer if MAIL_MAILER=ahasend
Mail::to('customer@example.com')->send(new OrderShipped($order));

// Or target the driver explicitly
Mail::mailer('ahasend')
    ->to('customer@example.com')
    ->cc('manager@example.com')
    ->send(new OrderShipped($order));
```

### 3. Example Mailable

[](#3-example-mailable)

```
