example.com in the sender addresses with your verified domain. Create the HTML, CSV, JSON and attachment files that an example names. The scripts use Bash, and the ones that read JSON need jq. Sends use --sandbox, so no email is delivered.
Transactional Emails
Order Confirmation
Password Reset
Account Verification
--tag can be given several times, and it also splits on commas, so --tag signup,verification sets two tags.
Lifecycle Notifications
Account Activity Digest
~/.ahasend/ that holds them, which you can pass back to --recipients. Exit codes lists what each other code means.
Account Feature Notifications
Pending Order Reminder
--schedule takes a relative time, such as 2h from now, or an RFC 3339 time. The API takes a time in the future and at most 7 days ahead.
Notification Systems
Real-Time Alerts
Daily Reports
Webhook Integration
Process Webhook Events
payload.type and payload.data.recipient. The listener’s own output is text for people to read, so process the events in the receiver. See webhook verification and processing. Your receiver does not need to suppress bouncing addresses: AhaSend suppresses them itself, for a time that depends on the cause, as suppression durations lists.
Webhook Testing Pipeline
--non-interactive makes webhooks create fail on a missing flag instead of asking for it, and webhooks delete --force skips the confirmation prompt, which cancels the command when stdin holds no answer.
Automation Scripts
Exit Codes in Scripts
Every failure exits with a nonzero code, in every output format, soset -e, if, and CI steps stop on a failed command. The code tells the kind of failure, as exit codes lists. With --output json, stdout holds the API’s response, or the error, as JSON output describes.
CI/CD Email Notifications
checksums.txt, as binary download does, and adds its folder to the PATH of the later steps. The CLI reads no environment variables for credentials, so the send step passes the secrets with --api-key and --account-id. It gets the deployment’s environment name through env:, so the shell reads it as a variable and never runs it as code. The step fails when the send fails, because the CLI exits with a nonzero code.

