Skip to main content
AhaSend works with Symfony Mailer’s SMTP bridge; this guide installs it, sends a sandbox email and adds a production sending script. Before sending, verify your domain and create an SMTP credential. Use a sandbox credential for these examples so no email is delivered. Keep the username and password in your server’s secret store. Use PHP 8.4.1 or newer and Composer for the Symfony 8.1 packages below. The AhaSend bridge is a real Symfony package. In the tested 8.1 release, its API transport uses legacy API v1; this guide uses SMTP. Do not put a v2 API key in that release’s API transport.

Install the Mailer

Set SMTP_USERNAME, SMTP_PASSWORD to a sandbox SMTP credential and AHASEND_FROM to your verified sender. Save quick-send.php:
quick-send.php
Run php quick-send.php. A transport failure raises an exception and exits with an error.

Use the Symfony Recipe in Your App

In an existing Symfony app using Flex, run the install command above to add Mailer and its configuration recipe. Set MAILER_DSN in the server’s secret store to the following value, replacing and URL-encoding the username and password. For local work, put this setting in .env.local, excluded from Git. Symfony loads that file when the application starts.
This recipe uses Symfony’s built-in SMTP transport so require_tls=true enforces STARTTLS. The 8.1 AhaSend bridge does not read that DSN option; the short bridge example above calls setRequireTls(true) directly. Keep the recipe’s framework.mailer.dsn setting connected to %env(MAILER_DSN)%. From the Symfony project root, run the following with the sandbox credential still configured. Replace sender@YOUR_DOMAIN with your verified sender. This command boots the app and reads .env.local; it bypasses Messenger to test the configured transport.
A successful command exits with status 0; check the AhaSend sandbox log too. Inject MailerInterface into your application’s mail service to use this configuration. The Symfony Mailer guide explains the recipe and Messenger delivery. See the SMTP reference for connection settings and TLS requirements.

Handle Failures Before Going Live

For a standalone worker, save this as send.php. Before running it, export MAILER_DSN, AHASEND_FROM and AHASEND_TO in its process environment; use the SMTP DSN above and AHASEND_TO=recipient@example.com while testing. This script loads Composer only: it does not boot Symfony or read .env.local. Keep using bin/console mailer:test for the Symfony app configuration.
send.php
Run php send.php. Check delivery events after SMTP acceptance. For an application worker, save the job ID and outcome, choose the recipient on the server, and keep email out of a public unauthenticated route. SMTP has no API idempotency key: a lost reply after submission can mean the message was accepted, so review an uncertain outcome before resending. When using the bridge directly in another worker, apply the same TLS requirement and timeout to its transport.