These commands need CLI v0.3.0 or later. Check your version with
ahasend --version, and upgrade if it is older.Prerequisites
Authenticate with a full API key. Campaign tasks need these scopes:
The examples also create a test list, which needs
lists:write and lists:delete. The shell examples need Bash and jq.
A campaign is a draft until it is sent, and only a draft can be changed or deleted. A draft shows whether it is ready to send and, when it is not, each issue in the way.
Draft and Test a Campaign
Save this file ascampaign.html. A campaign’s HTML must use {{ unsubscribe_url }} or {{ unsubscribe_link }}; see unsubscribe link:
campaign.html
news@example.com, and your own inbox in place of me@example.com. The script creates an empty test list, so the campaign has no audience, and sends only a test.
campaigns get shows whether a draft is ready and lists each issue as code: message, such as a missing sender, list, subject, preview text or design. Fix them with campaigns update, which sends only the flags you give. --list-id replaces the campaign’s lists, --from replaces the sender address and name together, and --subject "" and --preheader "" clear those fields.
campaigns test sends to up to 5 addresses, with placeholders for the contact’s fields. A campaign with issues is refused, and each issue is listed. Every issue blocks a test except unsubscribe_link_missing. The output shows the addresses the mail server accepted and refused, and the command exits with code 1 when any address was refused. When the server’s answer could not be read, the test may have gone out, so check the inboxes before you send another.
The API allows 50 test emails a UTC day for each account, one for each address of each test. A test that would pass that limit is refused with daily test send limit reached and exit code 8.
Send or Schedule a Campaign
campaigns send sends a draft now, or at the time given with --schedule: an RFC 3339 time or a relative one such as 2h. The API takes a time more than a minute ahead. The campaign then goes through list validation and review before it sends; follow its status with campaigns get.
campaigns send asks for confirmation first, as prompts describes. The prompt names the campaign and the send time in your local time zone, and a declined prompt sends nothing.
A campaign with issues is refused with exit code 4, and each issue is listed. With --output json, the issues are in the issues array of the API’s error body.
To stop a validating or scheduled campaign, return it to draft with campaigns unschedule. It does not ask for confirmation. A campaign that has queued mail cannot be unscheduled. To change the send time of a scheduled campaign, unschedule it and send it again.
Read Results
campaigns stats shows a campaign’s live counters, its rates and its stored report. The report is recounted from time to time, so check again later for new numbers.
campaigns recipients needs exactly one of --status and --bounce-classification. --status takes a status that campaigns stats counts, in any case, and --bounce-classification takes a bounce classification that campaigns stats counts, other than Unknown. campaigns list --status draft lists the campaigns in one status.
Campaign Templates
Campaign templates are designs that a campaign can copy withcampaigns create --campaign-template-id. A campaign template has no draft, subject or sender: changes apply at once, and campaigns already made from it keep their own copies. A campaign can be made from a template only once the template has HTML.
Continue the script. These commands make a campaign template from campaign.html, start a draft campaign from it, and delete both.
--campaign-template-id cannot be combined with --editor, --mjml-file, --html-file or --text-file.
Delete the Test Campaign
Finish the script by deleting the draft campaign, then the test list. The API refuses to delete a list while a campaign that still needs it refers to it.ahasend campaigns list --status draft, ahasend campaigns templates list and ahasend lists list --name "Docs test", and delete each with campaigns delete, campaigns templates delete or lists delete. Delete the campaigns before the list.
campaigns delete and campaigns templates delete ask for confirmation first; see prompts. To copy a campaign in any status into a new draft, use campaigns duplicate. Without --name, the copy is named “Copy of” and the campaign’s name.
Command Flags
These flags come from the CLI’s--help. All commands also accept the global flags.

