PHPackages                             postalsys/emailengine-php - 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. postalsys/emailengine-php

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

postalsys/emailengine-php
=========================

Modern PHP SDK for EmailEngine - Send and receive emails via REST API

v1.3.0(5mo ago)23.2k1MITPHPPHP &gt;=8.1CI passing

Since Dec 31Pushed 5mo ago1 watchersCompare

[ Source](https://github.com/postalsys/emailengine-php)[ Packagist](https://packagist.org/packages/postalsys/emailengine-php)[ Docs](https://emailengine.app)[ RSS](/packages/postalsys-emailengine-php/feed)WikiDiscussions master Synced yesterday

READMEChangelog (2)Dependencies (4)Versions (7)Used By (0)

EmailEngine PHP SDK
===================

[](#emailengine-php-sdk)

[![Tests](https://github.com/postalsys/emailengine-php/actions/workflows/tests.yml/badge.svg)](https://github.com/postalsys/emailengine-php/actions/workflows/tests.yml)[![PHP Version](https://camo.githubusercontent.com/04744bae0a61d2ffe29c26f07a9612eae20445fc6feaeb77b3af1f0e9be6447c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e312d3838393242462e737667)](https://php.net/)[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)

Modern PHP SDK for [EmailEngine](https://emailengine.app/) - the self-hosted email gateway that provides a REST API for IMAP and SMTP operations.

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

[](#requirements)

- PHP 8.1 or higher
- Composer
- EmailEngine instance

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

[](#installation)

```
composer require postalsys/emailengine-php
```

Quick Start
-----------

[](#quick-start)

```
use Postalsys\EmailEnginePhp\EmailEngine;

$client = new EmailEngine(
    accessToken: 'your-access-token',
    baseUrl: 'http://localhost:3000',
);

// List all accounts
$accounts = $client->accounts->list();

// Send an email
$result = $client->messages->submit('account-id', [
    'from' => ['name' => 'Sender', 'address' => 'sender@example.com'],
    'to' => [['name' => 'Recipient', 'address' => 'recipient@example.com']],
    'subject' => 'Hello from EmailEngine PHP SDK',
    'text' => 'This is a test email.',
    'html' => 'This is a test email.',
]);
```

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

[](#configuration)

### Constructor Parameters

[](#constructor-parameters)

```
$client = new EmailEngine(
    accessToken: 'your-access-token',      // Required: API access token
    baseUrl: 'http://localhost:3000',       // EmailEngine base URL (default: localhost:3000)
    serviceSecret: 'your-service-secret',   // For verifying webhook signatures
    redirectUrl: 'http://your-app/callback', // Default redirect URL for hosted auth
    timeout: 30,                            // Request timeout in seconds
);
```

### Factory Method (Legacy Compatibility)

[](#factory-method-legacy-compatibility)

```
$client = EmailEngine::fromOptions([
    'access_token' => 'your-access-token',
    'ee_base_url' => 'http://localhost:3000',
    'service_secret' => 'your-service-secret',
    'redirect_url' => 'http://your-app/callback',
]);
```

Resources
---------

[](#resources)

The SDK provides access to all EmailEngine API endpoints through resource classes:

ResourceDescription`$client->accounts`Account management (CRUD, sync, reconnect)`$client->messages`Message operations (list, read, send, search)`$client->mailboxes`Mailbox management (create, rename, delete)`$client->outbox`Queued message management`$client->settings`System and webhook settings`$client->tokens`Access token management`$client->templates`Email template management`$client->gateways`SMTP gateway configuration`$client->oauth2`OAuth2 application management`$client->webhooks`Webhook route management`$client->stats`System statistics and utilities`$client->blocklists`Blocklist managementExamples
--------

[](#examples)

### Account Management

[](#account-management)

```
// Create a new account
$account = $client->accounts->create([
    'account' => 'my-account',
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'imap' => [
        'host' => 'imap.example.com',
        'port' => 993,
        'secure' => true,
        'auth' => ['user' => 'john@example.com', 'pass' => 'password'],
    ],
    'smtp' => [
        'host' => 'smtp.example.com',
        'port' => 465,
        'secure' => true,
        'auth' => ['user' => 'john@example.com', 'pass' => 'password'],
    ],
]);

// Get account info
$info = $client->accounts->get('my-account');
echo "Account state: " . $info['state'];

// List all accounts
$accounts = $client->accounts->list(['page' => 0, 'pageSize' => 20]);

// Force reconnection
$client->accounts->reconnect('my-account');

// Delete account
$client->accounts->delete('my-account');
```

### Messages

[](#messages)

```
// List messages in INBOX
$messages = $client->messages->list('my-account', [
    'path' => 'INBOX',
    'pageSize' => 50,
]);

// Get message details
$message = $client->messages->get('my-account', 'message-id', [
    'textType' => 'html',
]);

// Search messages
$results = $client->messages->search('my-account', [
    'path' => 'INBOX',
    'search' => [
        'unseen' => true,
        'from' => 'important@example.com',
    ],
]);

// Update message flags
$client->messages->update('my-account', 'message-id', [
    'flags' => ['add' => ['\\Seen', '\\Flagged']],
]);

// Move message
$client->messages->move('my-account', 'message-id', 'Archive');

// Delete message
$client->messages->delete('my-account', 'message-id');

// Bulk operations
$client->messages->bulkUpdate('my-account', [
    'path' => 'INBOX',
    'messages' => ['msg-1', 'msg-2', 'msg-3'],
    'flags' => ['add' => ['\\Seen']],
]);
```

### Sending Emails

[](#sending-emails)

```
// Basic email
$result = $client->messages->submit('my-account', [
    'from' => ['name' => 'Sender', 'address' => 'sender@example.com'],
    'to' => [['name' => 'Recipient', 'address' => 'recipient@example.com']],
    'cc' => [['address' => 'cc@example.com']],
    'subject' => 'Test Subject',
    'text' => 'Plain text content',
    'html' => 'HTML content',
]);

// With attachments
$result = $client->messages->submit('my-account', [
    'from' => ['address' => 'sender@example.com'],
    'to' => [['address' => 'recipient@example.com']],
    'subject' => 'Email with attachment',
    'text' => 'Please see attached.',
    'attachments' => [
        [
            'filename' => 'document.pdf',
            'content' => base64_encode(file_get_contents('document.pdf')),
            'contentType' => 'application/pdf',
        ],
    ],
]);

// Using templates
$result = $client->messages->submit('my-account', [
    'to' => [['name' => 'John', 'address' => 'john@example.com']],
    'template' => 'welcome-email',
    'render' => [
        'name' => 'John',
        'company' => 'Acme Inc',
    ],
]);

// With idempotency key (prevents duplicates)
$result = $client->messages->submit('my-account', [
    'to' => [['address' => 'recipient@example.com']],
    'subject' => 'Important email',
    'text' => 'Content',
], [
    'idempotencyKey' => 'unique-key-12345',
]);

// Scheduled send
$result = $client->messages->submit('my-account', [
    'to' => [['address' => 'recipient@example.com']],
    'subject' => 'Scheduled email',
    'text' => 'This will be sent later',
    'sendAt' => '2024-12-25T10:00:00Z',
]);
```

### Download Attachments

[](#download-attachments)

```
// Download and stream an attachment directly to the browser
$client->download("/v1/account/my-account/attachment/AAAAAQAABRQ");
```

### Mailbox Management

[](#mailbox-management)

```
// List mailboxes
$mailboxes = $client->mailboxes->list('my-account', ['counters' => true]);

// Create mailbox
$client->mailboxes->create('my-account', 'INBOX/Projects');

// Rename mailbox
$client->mailboxes->rename('my-account', 'INBOX/OldName', 'INBOX/NewName');

// Delete mailbox
$client->mailboxes->delete('my-account', 'INBOX/ToDelete');

// Subscribe/unsubscribe
$client->mailboxes->subscribe('my-account', 'Archive');
$client->mailboxes->unsubscribe('my-account', 'Spam');
```

### Webhook Settings

[](#webhook-settings)

```
// Get webhook settings
$webhooks = $client->settings->getWebhooks();

// Configure webhooks
$client->settings->setWebhooks([
    'enabled' => true,
    'url' => 'https://your-app.com/webhooks',
    'events' => ['messageNew', 'messageUpdated', 'messageSent'],
    'headers' => ['Received', 'List-ID'],
    'text' => 2048, // Include first 2KB of text content
]);
```

### Hosted Authentication

[](#hosted-authentication)

Generate URLs for EmailEngine's hosted authentication form. This method calls the EmailEngine API to generate a secure authentication URL with server-side nonce and timestamp for replay attack protection.

```
$client = new EmailEngine(
    accessToken: 'your-token',
    baseUrl: 'http://localhost:3000',
    redirectUrl: 'http://your-app/auth-callback',
);

// Generate auth URL with basic options
$authUrl = $client->getAuthenticationUrl([
    'account' => null, // null = auto-generate account ID
    'name' => 'User Name',
    'email' => 'user@example.com',
]);

// Redirect user to $authUrl
header('Location: ' . $authUrl);
```

#### Available Parameters

[](#available-parameters)

ParameterTypeDescription`account`string|nullAccount ID (null to auto-generate)`name`stringDisplay name for the account`email`stringEmail address hint`redirectUrl`stringOverride default redirect URL`type`stringAccount type (e.g., 'imap', 'gmail', 'outlook')`delegated`boolEnable delegated access`syncFrom`stringISO 8601 date to sync messages from`notifyFrom`stringISO 8601 date to send notifications from`subconnections`arrayList of shared mailboxes to connect`path`string|arrayMailbox path(s) to monitor```
// Example with all parameters
$authUrl = $client->getAuthenticationUrl([
    'account' => 'user-123',
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'type' => 'gmail',
    'delegated' => true,
    'syncFrom' => '2024-01-01T00:00:00Z',
    'notifyFrom' => '2024-01-01T00:00:00Z',
    'subconnections' => ['Shared Mailbox'],
    'path' => ['INBOX', 'Sent'],
]);
```

### Webhook Signature Verification

[](#webhook-signature-verification)

Verify webhook signatures to ensure requests are authentically from EmailEngine. Requires the `serviceSecret` to be configured.

```
$client = new EmailEngine(
    accessToken: 'your-token',
    baseUrl: 'http://localhost:3000',
    serviceSecret: 'your-service-secret',
);

// Get the raw request body and signature header
$body = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_EE_WH_SIGNATURE'] ?? '';

if ($client->verifyWebhookSignature($body, $signature)) {
    // Signature is valid - process the webhook
    $payload = json_decode($body, true);
    // ... handle webhook event
} else {
    // Invalid signature - reject the request
    http_response_code(401);
    exit('Invalid signature');
}
```

### Outbox Management

[](#outbox-management)

```
// List queued messages
$queue = $client->outbox->list(['account' => 'my-account']);

// Get queued message details
$item = $client->outbox->get('queue-id');

// Cancel scheduled message
$client->outbox->cancel('queue-id');
```

### System Statistics

[](#system-statistics)

```
// Get system stats
$stats = $client->stats->get();
echo "EmailEngine version: " . $stats['version'];
echo "Connected accounts: " . $stats['connections']['connected'];

// Auto-discover email settings
$config = $client->stats->autoconfig('user@gmail.com');
```

Error Handling
--------------

[](#error-handling)

The SDK throws specific exceptions for different error types:

```
use Postalsys\EmailEnginePhp\Exceptions\AuthenticationException;
use Postalsys\EmailEnginePhp\Exceptions\AuthorizationException;
use Postalsys\EmailEnginePhp\Exceptions\NotFoundException;
use Postalsys\EmailEnginePhp\Exceptions\ValidationException;
use Postalsys\EmailEnginePhp\Exceptions\RateLimitException;
use Postalsys\EmailEnginePhp\Exceptions\ServerException;
use Postalsys\EmailEnginePhp\Exceptions\EmailEngineException;

try {
    $account = $client->accounts->get('unknown-account');
} catch (NotFoundException $e) {
    echo "Account not found: " . $e->getMessage();
    echo "Error code: " . $e->getErrorCode();
} catch (AuthenticationException $e) {
    echo "Invalid API token";
} catch (ValidationException $e) {
    echo "Validation error: " . $e->getMessage();
    print_r($e->getDetails());
} catch (RateLimitException $e) {
    echo "Rate limited. Retry after: " . $e->getRetryAfter() . " seconds";
} catch (EmailEngineException $e) {
    echo "API error: " . $e->getMessage();
}
```

Raw API Requests
----------------

[](#raw-api-requests)

For endpoints not covered by resource classes:

```
// GET request
$response = $client->request('GET', '/v1/some-endpoint', query: ['param' => 'value']);

// POST request
$response = $client->request('POST', '/v1/some-endpoint', data: ['key' => 'value']);

// With custom headers
$response = $client->request('POST', '/v1/some-endpoint',
    data: ['key' => 'value'],
    headers: ['X-Custom-Header' => 'value']
);
```

Testing
-------

[](#testing)

### Local Testing

[](#local-testing)

```
# Install dependencies
make install

# Run unit tests
make test

# Run tests with coverage
make test-coverage

# Run static analysis
make phpstan

# Check code style
make lint
```

### Docker Testing

[](#docker-testing)

Test across multiple PHP versions using Docker:

```
# Run unit tests on PHP 8.3
make docker-test

# Run tests on all PHP versions (8.1, 8.2, 8.3, 8.4)
make docker-test-all

# Run integration tests with real EmailEngine
make docker-integration
```

### Integration Testing

[](#integration-testing)

Integration tests run against a real EmailEngine instance:

```
# Start EmailEngine and Redis
make docker-up

# Run integration tests (auto-generates access token)
make docker-integration

# View EmailEngine logs
make docker-logs

# Stop services
make docker-down
```

**Note:** EmailEngine without a license suspends workers after 15 minutes. Integration tests are designed to complete within this time window. If you need more time, restart EmailEngine:

```
docker compose restart emailengine
```

### Manual Integration Testing

[](#manual-integration-testing)

To run integration tests against your own EmailEngine instance:

```
# Generate a token using EmailEngine CLI
emailengine tokens issue -d "Test" -s "*" --dbs.redis="redis://localhost:6379"

# Run tests with your token
EMAILENGINE_ACCESS_TOKEN="your-token" \
EMAILENGINE_BASE_URL="http://localhost:3000" \
./vendor/bin/phpunit --testsuite integration
```

Legacy Compatibility
--------------------

[](#legacy-compatibility)

The SDK maintains backward compatibility with the old API:

```
// Old way (still works, but deprecated)
use EmailEnginePhp\EmailEngine;

$ee = new EmailEngine([
    'access_token' => 'token',
    'ee_base_url' => 'http://localhost:3000',
    'service_secret' => 'secret',
    'redirect_url' => 'http://callback.url',
]);

$ee->get_webhook_settings();
$ee->set_webhook_settings(['enabled' => true]);
$ee->get_authentication_url(['account' => null]);
```

License
-------

[](#license)

MIT License - see [LICENSE](LICENSE) file.

Links
-----

[](#links)

- [EmailEngine](https://emailengine.app/) - Self-hosted email gateway
- [EmailEngine Documentation](https://api.emailengine.app/) - API reference
- [GitHub Repository](https://github.com/postalsys/emailengine-php)

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance72

Regular maintenance activity

Popularity24

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 88.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~372 days

Total

5

Last Release

156d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2ba8d533b372ed385052a9c641aa8044d61f788192eadb95d920e6dfc3794bd9?d=identicon)[postalsys](/maintainers/postalsys)

---

Top Contributors

[![andris9](https://avatars.githubusercontent.com/u/132242?v=4)](https://github.com/andris9 "andris9 (16 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (2 commits)")

---

Tags

apisdkemailsmtpimapemailengine

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/postalsys-emailengine-php/health.svg)

```
[![Health](https://phpackages.com/badges/postalsys-emailengine-php/health.svg)](https://phpackages.com/packages/postalsys-emailengine-php)
```

###  Alternatives

[aws/aws-sdk-php

AWS SDK for PHP - Use Amazon Web Services in your PHP project

6.3k543.5M2.6k](/packages/aws-aws-sdk-php)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

273.0k](/packages/eslazarev-wildberries-sdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
