---
title: "Bring-your-own-key email: two ways to build the mailer"
description: "The two mailer strategies for a team's own email provider, laravel and dsn, and how they compare."
---

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

# Bring-your-own-key email: two ways to build the mailer

When a form uses a team's own email provider, quickforms builds a mailer for that send from the team's decrypted keys. There are two implementations. Both are in the codebase, both are tested, and you pick one with an env variable:

```bash
QUICKFORMS_MAIL_TRANSPORT=laravel   # default
QUICKFORMS_MAIL_TRANSPORT=dsn
```

Everything else stays the same either way: the delivery log, retries, sandbox previews and the provider UI/API.

| | `laravel` | `dsn` |
| --- | --- | --- |
| Code | `app/Services/Mail/LaravelMailerFactory.php` | `app/Services/Mail/DsnMailerFactory.php` |
| How | `Mail::build([...])` with Laravel's own `resend`, `postmark`, `mailgun`, `ses` and `smtp` drivers, the same config shape as `config/mail.php` | `Mail::build(['transport' => 'dsn', 'dsn' => 'postmark+api://KEY@default'])` through a small `dsn` transport registered in `AppServiceProvider` |
| Mailchimp Transactional | Not a Laravel driver, so it uses the DSN path | Native (`mandrill+api://`) |

## What each transport ends up being

From `tests/Feature/Quickforms/MailTransportsTest.php`:

| Provider | `laravel` | `dsn` |
| --- | --- | --- |
| Resend | Laravel `ResendTransport` (official `resend/resend-php` SDK) | Symfony `ResendApiTransport` |
| Postmark | Symfony `PostmarkApiTransport` | Same |
| Mailgun | Symfony `MailgunHttpTransport` (sends raw MIME) | Symfony `MailgunApiTransport` (JSON API) |
| Amazon SES | Laravel `SesTransport` (AWS SDK for PHP) | Symfony `SesApiAsyncAwsTransport` (AsyncAws) |
| SMTP | Symfony `EsmtpTransport` | Same |
| Mailchimp Transactional | Symfony `MandrillApiTransport` | Same |

Postmark, SMTP and Mailchimp Transactional are identical either way. The real differences are Resend, Mailgun and SES.

## Laravel drivers (`laravel`)

Pros

- It's the Laravel way. Anyone who knows `config/mail.php` can read the mapping, and the platform mailer and tenant mailers are configured the same way.
- Laravel maintains the drivers, so fixes and new options (for example Postmark message streams, SES options) arrive with framework upgrades.
- Resend and SES go through the providers' official SDKs.

Cons

- **Platform key fallback.** When a key is missing from the array, Laravel's drivers quietly use the platform's keys from `config/services.php`. For Mailgun it swaps in the whole platform config if `secret` is absent. Without a guard, a tenant with a gap in their credentials would send through your account. quickforms guards this: `IncompleteMailCredentials` refuses to build a tenant mailer with any required key blank, and the SES session token is pinned to null. There's a test for each strategy that sets platform keys and checks they are never used. The risk is that a future driver or option added without the guard reopens the hole.
- **Heavier dependencies.** It needs `resend/resend-php` (about 0.4 MB) and `aws/aws-sdk-php` (about 69 MB in `vendor`). That's fine on Laravel Cloud, but it's a big package to carry for one driver.
- Mailchimp Transactional still needs the DSN path, so there are two mechanisms in play.

## Symfony DSNs (`dsn`)

Pros

- **No fallback possible.** A DSN carries every credential, and Symfony has no notion of your platform keys, so a missing key fails instead of borrowing yours. (The same guard runs anyway, for a clearer error.)
- One uniform mechanism for all six providers, Mailchimp Transactional included.
- Light dependencies: the Symfony bridges and `symfony/http-client` together come to about 1.7 MB, and SES uses AsyncAws instead of the full AWS SDK.

Cons

- Less familiar to Laravel developers, and it relies on a custom `dsn` transport registered in `AppServiceProvider`.
- Credentials have to be URL-encoded into the DSN. The factory does this, and the SES and SMTP tests cover keys with `/`, `+` and `@` in them.
- A DSN is a single string holding secrets, so it should never be logged. The delivery log records the exception message, never the DSN itself.

## Recommendation

Either is fine to ship, and both are fully tested. If you'd rather stay close to Laravel and keep up with framework changes for free, use `laravel` (the default) and keep the guard. If you'd rather have the lighter install and fallback-proof credentials by construction, use `dsn`. Once you've picked one, the other factory and its packages can be deleted:

- Keeping `laravel`: you can drop the `symfony/resend-mailer` and `symfony/amazon-mailer` bridges. Keep `symfony/mailchimp-mailer`, plus the Postmark and Mailgun bridges that Laravel's drivers use.
- Keeping `dsn`: you can drop `resend/resend-php` and `aws/aws-sdk-php`.

Source: https://docs.getquickforms.com/email/mail-transports/index.mdx
